Identyfikatory GUID mogą wydawać się naturalnym wyborem dla twojego klucza podstawowego - a jeśli naprawdę musisz, prawdopodobnie możesz argumentować, aby użyć go dla KLUCZA PODSTAWOWEGO tabeli. Zdecydowanie odradzam korzystanie z kolumny GUID jako klucza klastrowania , co SQL Server domyślnie robi, chyba że wyraźnie powiesz, żeby tego nie robił .
Naprawdę musisz rozdzielić dwa problemy:
klucz podstawowy jest logiczną konstrukcją - jeden z kluczy kandydujących, który jednoznacznie identyfikuje i niezawodnie każdego wiersza w tabeli. To może być cokolwiek, naprawdę - W INT
, A GUID
, łańcuch - wybrać to, co sprawia, że największy sens dla scenariusza.
klucz klastrów (kolumna lub kolumn, które definiują „klastrowego indeksu” na stole) - jest to fizyczne rzeczy związane z magazynowaniem, a tu, mały, stabilny, coraz większa typ danych jest najlepszym pick - INT
albo BIGINT
jako swój Domyślna opcja.
Domyślnie klucz podstawowy w tabeli programu SQL Server jest również używany jako klucz klastrowania - ale nie musi tak być! Osobiście widziałem ogromny wzrost wydajności, gdy dzielę poprzedni klucz podstawowy / klastrowany oparty na GUID na dwa osobne klucze - klucz podstawowy (logiczny) na GUID i klucz grupowania (porządkowania) w osobnej INT IDENTITY(1,1)
kolumnie.
Jak Kimberly Tripp - Królowa Indeksowania - i inni wspominali wiele razy - GUID
klucz klastrowania nie jest optymalny, ponieważ ze względu na jego losowość doprowadzi do ogromnej fragmentacji stron i indeksów oraz ogólnie złej wydajności.
Tak, wiem - jest newsequentialid()
w SQL Server 2005 i nowszych - ale nawet to nie jest w pełni i całkowicie sekwencyjne, a zatem cierpi z powodu tych samych problemów co GUID
- tylko trochę mniej wyraźnie.
Jest jeszcze jeden problem do rozważenia: klucz klastrowania w tabeli zostanie dodany do każdego wpisu w każdym indeksie nieklastrowanym w tabeli - dlatego naprawdę chcesz mieć pewność, że jest tak mały, jak to możliwe. Zazwyczaj INT
ponad 2 miliardy wierszy powinno wystarczyć do przeważającej większości tabel - w porównaniu z GUID
kluczem klastrowym możesz zaoszczędzić sobie setki megabajtów pamięci na dysku i w pamięci serwera.
Szybkie obliczenia - użycie INT
vs. GUID
jako klucza podstawowego i klucza grupowania:
- Tabela bazowa z 1 000 000 wierszy (3,8 MB vs. 15,26 MB)
- 6 indeksów nieklastrowych (22,89 MB vs. 91,55 MB)
RAZEM: 25 MB vs. 106 MB - i to tylko na jednym stole!
Więcej jedzenia do przemyślenia - doskonałe rzeczy Kimberly Tripp - przeczytaj, przeczytaj jeszcze raz, przetrawiaj! To naprawdę ewangelia indeksowania SQL Server.
PS: oczywiście, jeśli masz do czynienia z zaledwie kilkuset lub kilkoma tysiącami wierszy - większość z tych argumentów tak naprawdę nie będzie miała na ciebie większego wpływu. Jednak: jeśli wejdziesz w dziesiątki lub setki tysięcy wierszy lub zaczniesz liczyć w milionach - wtedy punkty te staną się bardzo ważne i bardzo ważne do zrozumienia.
Aktualizacja: jeśli chcesz mieć PKGUID
kolumnę jako klucz podstawowy (ale nie klucz klastrowania), a kolejną kolumnę MYINT
( INT IDENTITY
) jako klucz klastrowania - użyj tego:
CREATE TABLE dbo.MyTable
(PKGUID UNIQUEIDENTIFIER NOT NULL,
MyINT INT IDENTITY(1,1) NOT NULL,
.... add more columns as needed ...... )
ALTER TABLE dbo.MyTable
ADD CONSTRAINT PK_MyTable
PRIMARY KEY NONCLUSTERED (PKGUID)
CREATE UNIQUE CLUSTERED INDEX CIX_MyTable ON dbo.MyTable(MyINT)
Zasadniczo: musisz tylko wyraźnie powiedzieć PRIMARY KEY
, że jest to ograniczenie NONCLUSTERED
(w przeciwnym razie domyślnie jest on tworzony jako indeks klastrowany) - a następnie tworzysz drugi indeks, który jest zdefiniowany jakoCLUSTERED
To zadziała - i jest to poprawna opcja, jeśli masz istniejący system, który musi zostać „przeprojektowany” pod kątem wydajności. W przypadku nowego systemu, jeśli zaczynasz od zera i nie jesteś w scenariuszu replikacji, to zawsze wybrałbym ID INT IDENTITY(1,1)
jako mój klastrowany klucz podstawowy - znacznie bardziej wydajny niż cokolwiek innego!