GUIDs scheinen eine natürliche Wahl für Ihren Primärschlüssel zu sein - und wenn Sie es wirklich müssen, könnten Sie wahrscheinlich argumentieren, sie für den PRIMARY KEY der Tabelle zu verwenden. Ich würde dringend empfehlen , die GUID-Spalte nicht als Clustering-Schlüssel zu verwenden , was SQL Server standardmäßig tut, es sei denn, Sie weisen ausdrücklich an, dies nicht zu tun .
Sie müssen wirklich zwei Punkte auseinander halten:
Der Primärschlüssel ist ein logisches Konstrukt - einer der Kandidatenschlüssel, der jede Zeile in Ihrer Tabelle eindeutig und zuverlässig identifiziert. Dies kann wirklich alles sein - eine INT
, eine GUID
, eine Zeichenfolge - wählen Sie aus, was für Ihr Szenario am sinnvollsten ist.
der Clustering-Schlüssel (die Spalte oder Spalten, die den "Clustered-Index" in der Tabelle definieren) - dies ist eine Sache, die sich auf den physischen Speicher bezieht, und hier ist ein kleiner, stabiler, ständig wachsender Datentyp Ihre beste Wahl - INT
oder BIGINT
als Ihre Standardoption.
Standardmäßig wird der Primärschlüssel in einer SQL Server-Tabelle auch als Clustering-Schlüssel verwendet - aber das muss nicht so sein! Ich persönlich habe massive Leistungssteigerungen festgestellt, als der vorherige GUID-basierte Primär- / Clusterschlüssel in zwei separate Schlüssel aufgeteilt wurde - den Primärschlüssel (logisch) in der GUID und den Clusterschlüssel (Reihenfolge) in einer separaten INT IDENTITY(1,1)
Spalte.
Wie Kimberly Tripp - die Königin der Indizierung - und andere schon oft gesagt haben - a, GUID
da der Clustering-Schlüssel nicht optimal ist, da er aufgrund seiner Zufälligkeit zu einer massiven Fragmentierung von Seiten und Indizes und zu einer allgemein schlechten Leistung führt.
Ja, ich weiß - es gibt newsequentialid()
in SQL Server 2005 und höher -, aber selbst das ist nicht wirklich und vollständig sequentiell und leidet daher auch unter den gleichen Problemen wie das GUID
- nur ein bisschen weniger prominent.
Dann ist noch ein weiteres Problem zu berücksichtigen: Der Clustering-Schlüssel in einer Tabelle wird jedem Eintrag in jedem nicht geclusterten Index in Ihrer Tabelle hinzugefügt. Sie möchten also wirklich sicherstellen, dass er so klein wie möglich ist. In der Regel sollte ein INT
mit 2+ Milliarden Zeilen für die überwiegende Mehrheit der Tabellen ausreichen - und im Vergleich zu einem GUID
als Clustering-Schlüssel können Sie sich Hunderte von Megabyte Speicherplatz auf der Festplatte und im Serverspeicher sparen.
Schnelle Berechnung - Verwenden von INT
vs. GUID
als Primär- und Clustering-Schlüssel:
- Basistabelle mit 1'000'000 Zeilen (3,8 MB gegenüber 15,26 MB)
- 6 nicht gruppierte Indizes (22,89 MB gegenüber 91,55 MB)
GESAMT: 25 MB vs. 106 MB - und das nur auf einem Tisch!
Noch ein Denkanstoß - exzellentes Zeug von Kimberly Tripp - lesen Sie es, lesen Sie es noch einmal, verdauen Sie es! Es ist wirklich das Evangelium der SQL Server-Indizierung.
PS: Wenn Sie es nur mit ein paar hundert oder ein paar tausend Zeilen zu tun haben, haben die meisten dieser Argumente natürlich keinen großen Einfluss auf Sie. Allerdings: Wenn Sie in die Dutzende oder Hunderte von Tausenden von Zeilen, oder Sie starten das Zählen in Millionen - dann werden diese Punkte sehr wichtig und sehr wichtig zu verstehen.
Update: Wenn Sie Ihre PKGUID
Spalte als Primärschlüssel (aber nicht als Clustering-Schlüssel) und eine andere Spalte MYINT
( INT IDENTITY
) als Clustering-Schlüssel verwenden möchten, verwenden Sie Folgendes:
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)
Grundsätzlich gilt: Sie müssen der Einschränkung nur explizit mitteilen PRIMARY KEY
, dass dies der Fall ist NONCLUSTERED
(andernfalls wird sie standardmäßig als Clustered-Index erstellt). Anschließend erstellen Sie einen zweiten Index, der als definiert istCLUSTERED
Dies funktioniert - und es ist eine gültige Option, wenn Sie ein vorhandenes System haben, das für die Leistung "überarbeitet" werden muss. Wenn Sie bei einem neuen System von vorne beginnen und sich nicht in einem Replikationsszenario befinden, würde ich immer ID INT IDENTITY(1,1)
meinen Cluster-Primärschlüssel auswählen - viel effizienter als alles andere!