sql >> Database >  >> RDS >> Sqlserver

GUID-prestaties

GUID s lijkt misschien een natuurlijke keuze voor je primaire sleutel - en als het echt moet, zou je waarschijnlijk kunnen argumenteren om het te gebruiken voor de PRIMAIRE SLEUTEL van de tabel. Wat ik sterk zou aanraden niet te doen is gebruik maken van de GUID kolom als de clustersleutel , wat SQL Server standaard doet, tenzij u specifiek aangeeft dat niet te doen.

Je moet echt twee zaken uit elkaar houden:

  1. de primaire sleutel is een logische constructie - een van de kandidaatsleutels die elke rij in uw tabel op unieke en betrouwbare wijze identificeert. Dit kan werkelijk van alles zijn - een INT , een GUID , een string - kies wat het meest logisch is voor uw scenario.

  2. de clustersleutel (de kolom of kolommen die de geclusterde index definiëren) op tafel) - dit is een fysiek opslaggerelateerd ding, en hier is een klein, stabiel, steeds groter wordend gegevenstype de beste keuze - INT of BIGINT als uw standaardoptie.

Standaard wordt de primaire sleutel op een SQL Server-tabel ook gebruikt als de clustersleutel - maar dat hoeft niet zo te zijn! Ik heb persoonlijk enorme prestatieverbeteringen gezien bij het opsplitsen van de vorige op GUID gebaseerde primaire / geclusterde sleutel in twee afzonderlijke sleutels - de primaire (logische) sleutel op de GUID en de clustering (bestel) sleutel op een afzonderlijke INT IDENTITY(1,1) kolom.

Als Kimberly Tripp - de Queen of Indexing - en anderen hebben al heel vaak verklaard - een GUID omdat de clustersleutel niet optimaal is, omdat dit door zijn willekeur zal leiden tot enorme pagina- en indexfragmentatie en tot over het algemeen slechte prestaties.

Ja, ik weet het - er is newsequentialid() in SQL Server 2005 en hoger - maar zelfs dat is niet echt en volledig sequentieel en heeft dus ook last van dezelfde problemen als de GUID - alleen iets minder prominent.

Dan is er nog een ander probleem om te overwegen:de clustersleutel op een tabel wordt ook toegevoegd aan elk item op elke niet-geclusterde index op uw tabel - dus u wilt er zeker van zijn dat deze zo klein mogelijk is. Normaal gesproken zou een INT met meer dan 2 miljard rijen voldoende moeten zijn voor de overgrote meerderheid van de tabellen - en vergeleken met een GUID als clustersleutel, kunt u honderden megabytes aan opslagruimte op schijf en in servergeheugen besparen.

Snelle berekening - met behulp van INT vs. GUID als primaire en clustersleutel:

  • Basistabel met 1.000.000 rijen (3,8 MB vs. 15,26 MB)
  • 6 niet-geclusterde indexen (22,89 MB versus 91,55 MB)

TOTAAL:25 MB versus 106 MB - en dat is slechts op een enkele tafel!

Nog wat stof tot nadenken - uitstekend werk van Kimberly Tripp - lees het, lees het nog eens, verwerk het! Het is eigenlijk het SQL Server-indexeringsevangelie.




  1. MySql-proceslijst gevuld met slaapvermeldingen die leiden tot te veel verbindingen?

  2. Importeer de gegevens uit de XML-bestanden in een MySQL-database

  3. Hoe ontleden een VARCHAR doorgegeven aan een opgeslagen procedure in SQL Server?

  4. Oracle SQL, vul ontbrekende waarde in met de dichtstbijzijnde niet-ontbrekende