Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Jakie są najlepsze praktyki dotyczące używania identyfikatora GUID jako klucza podstawowego, szczególnie w odniesieniu do wydajności?

Identyfikatory GUID mogą wydawać się naturalnym wyborem dla klucza podstawowego — a jeśli naprawdę musisz, prawdopodobnie możesz argumentować, aby użyć go jako klucza podstawowego tabeli. Czego zdecydowanie odradzam nie robić używa kolumny GUID jako klucza klastrowania , co SQL Server robi domyślnie, chyba że wyraźnie zabronisz mu tego.

Naprawdę musisz oddzielić dwa problemy:

  1. klucz podstawowy to konstrukcja logiczna — jeden z kluczy kandydujących, który jednoznacznie i niezawodnie identyfikuje każdy wiersz w tabeli. To może być naprawdę wszystko - INT , GUID , ciąg — wybierz, co jest najbardziej sensowne dla Twojego scenariusza.

  2. klucz klastrowania (kolumna lub kolumny, które definiują „indeks klastrowy” w tabeli) — jest to fizyczny rzecz związana z pamięcią masową, a tutaj najlepszym wyborem jest mały, stabilny, stale rosnący typ danych - INT lub BIGINT jako domyślną opcję.

Domyślnie klucz podstawowy w tabeli SQL Server jest również używany jako klucz klastrowy — ale nie musi tak być! Osobiście widziałem ogromny wzrost wydajności podczas dzielenia poprzedniego klucza podstawowego / klastrowego opartego na identyfikatorze GUID na dwa oddzielne klucze - klucz podstawowy (logiczny) w identyfikatorze GUID i klucz klastrowania (porządkujący) na oddzielnym INT IDENTITY(1,1) kolumna.

Jak Kimberly Tripp - królowa indeksowania - i inni wielokrotnie stwierdzali - GUID ponieważ klucz klastrowania nie jest optymalny, ponieważ ze względu na jego losowość doprowadzi do ogromnej fragmentacji stron i indeksów oraz ogólnie do złej wydajności.

Tak, wiem - jest newsequentialid() w SQL Server 2005 i nowszych - ale nawet to nie jest prawdziwie i w pełni sekwencyjne, a zatem również cierpi na te same problemy, co GUID - tylko trochę mniej widoczne.

Jest jeszcze jedna kwestia do rozważenia:klucz klastrowania w tabeli zostanie dodany do każdego wpisu w każdym indeksie nieklastrowanym w Twojej tabeli - dlatego naprawdę chcesz się upewnić, że jest on tak mały, jak to możliwe. Zazwyczaj INT z ponad 2 miliardami wierszy powinno wystarczyć dla większości tabel - w porównaniu z GUID jako klucz klastrowania możesz zaoszczędzić sobie setki megabajtów pamięci na dysku i w pamięci serwera.

Szybkie obliczenia - przy użyciu INT w porównaniu z GUID jako klucz podstawowy i klucz klastrowy:

  • Tabela podstawowa z 1 000 000 wierszy (3,8 MB vs. 15,26 MB)
  • 6 indeksów nieklastrowych (22,89 MB w porównaniu z 91,55 MB)

ŁĄCZNIE:25 MB vs. 106 MB - i to tylko na jednym stole!

Trochę więcej do myślenia - świetne rzeczy Kimberly Tripp - przeczytaj, przeczytaj jeszcze raz, przetrawij! To naprawdę ewangelia indeksowania SQL Server.

  • identyfikatory GUID jako klucz podstawowy i/lub klucz klastrowy
  • Debata o indeksach klastrowych trwa
  • Ciągle rosnący klucz klastrowania – ponownie debata na temat indeksów klastrowych!
  • Miejsce na dysku jest tanie – to nie o co chodzi!

PS:oczywiście, jeśli masz do czynienia z kilkoma setkami lub kilkoma tysiącami wierszy – większość z tych argumentów nie będzie miała na ciebie większego wpływu. Jednak:jeśli znajdziesz się w dziesiątkach lub setkach tysięcy wierszy lub zaczniesz liczyć w milionach - wtedy te punkty stają się bardzo ważne i bardzo ważne do zrozumienia.

Aktualizacja: jeśli chcesz mieć swój PKGUID kolumna jako klucz podstawowy (ale nie klucz klastrowania), a kolejna kolumna 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:wystarczy wyraźnie powiedz PRIMARY KEY ograniczenie, że jest NONCLUSTERED (w przeciwnym razie jest tworzony domyślnie jako indeks klastrowy) — a następnie tworzysz drugi indeks zdefiniowany jako CLUSTERED

To zadziała – i jest to ważna opcja, jeśli masz istniejący system, który wymaga „przeprojektowania” pod kątem wydajności. W przypadku nowego systemu, jeśli zaczynasz od zera i nie jesteś w scenariuszu replikacji, zawsze wybieram ID INT IDENTITY(1,1) jako mój klastrowany klucz podstawowy - znacznie bardziej wydajny niż cokolwiek innego!



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak usunąć z wielu tabel za pomocą INNER JOIN na serwerze SQL?

  2. DATETIME2FROMPARTS() Przykłady w SQL Server (T-SQL)

  3. SQL Server 2017:importowanie danych CSV z systemu Linux do Salesforce za pomocą SSIS

  4. Napraw „data jest niezgodna z int” w SQL Server podczas dodawania lub odejmowania od daty

  5. Jak używać wszystkich operatorów logicznych w SQL Server — samouczek SQL Server / TSQL, część 126