SQL Practice Blog – SQL Server, BizTalk und .NET Erfahrungen

SQL Server: NEWID() versus NEWSEQUENTIALID()

leave a comment »

Immer wieder habe ich die Diskussion unter Datenbankentwicklern und Softwareentwicklern ob ein eine Uniqueidentifier (GUID) als Primary Key geeignet ist. Prinzipiell gilt hier folgende Regel, benötigt man keine absolut eindeutigen und einzigartigen IDs so ist man mit dem Integer Datentyp in der Primary Key Spalte besser beraten.

Der Unterschied beginnt schon damit, das sich ein Integerwert in der Regel fortlaufend erhöht und damit eine minimale Fragmentation des Index bewirkt. Ein weiterer Vorteil von dem Datentyp Integer ist dessen Größe. Ein Integer benötigt im Vergleich zum einer GUID sehr wenig Speicherplatz.

Manchmal jedoch reicht ein Integer nicht aus. Soll z.B. ein Datensatz über ein Unternehmen mit verschiedenen Standorten hinweg eindeutig sein, so wählt man meist eine GUID als ID.

Was ist ein Uniqueidentifier (GUID)?

GUID bedeutet Globally Unique Identifier und ist eine eindeutige Binärzahl. Für gewöhnlich generiert kein anderer Computer auf dieser Welt eine bereits erzeugte GUID ein zweites Mal. Eine neue GUID kann mit dem T-SQL Befehl NEWID() erstellt werden. Dazu wird die ID der Netzwerkkarte mit einer eindeutigen Zahl welche von der CPU Uhr stammt kombiniert. Das ergibt einen Globally Unique Identifier.

Welche Möglichkeiten zu erzeugen einer GUID gibt es?

Mit dem SQL Server ist es auf zwei Wegen möglich eine GUID zu erzeugen. Der erste und bereits angesprochene Weg, ist das erstellen einer GUID mit Hilfe der NEWID() Funktion. Ein anderer Weg ist das erstellen einer sequentiellen GUID, hierbei wird die erstellte GUID immer größer sein als die zuvor erstellte GUID. Dadurch entsteht eine fortlaufende GUID. Die Funktion dafür lautet NEWSEQUENTIALID() und kann jedoch nur in der DEFAULT Anweisung beim erstellen oder bearbeiten einer Tabelle angegeben werden.

Praktisches Beispiel:

Wir erstellen eine Tabelle mit zwei Spalten, einer ID Spalte als Primary Key welcher mit NEWID() bzw. NEWSEQUENTIALID() automatisch erstellt wird und einer Value Spalte, wo ein beliebiger Wert gespeichert wird. In diese Tabelle fügen wir nun mit Hilfe einer Schleife 2000 Datensätze ein. Danach werden wir uns folgende Indikatoren ansehen:

  • Größe des Clustered Index
  • Fragmentierung des Clustered Index
  • Anzahl von Seiten die der Clustered Index benötigt

Als erstes erstellen wir eine Tabelle, welche in der ID Spalte eine GUID mit der NEWID() Funktion erstellt.

image 

image

Nun füllt eine WHILE Schleife die Tabelle mit 2000 Datensätzen. Die Funktion REPLICATE sorgt dafür das der Buchstabe A so oft repliziert wird wie der Wert Variable @i gesetzt ist.

Als nächsten Schritt müssen wir nun die drei Indikatoren auswerden. Um die Speicherplatzbelegung des Index auszulesen, bedienen wir uns der sp_spaceused Stored Procedure.

Um die Fragmentierung und die Anzahl der Seiten auslesen zu können, sprechen wir die sys.dm_db_index_physical_stats Funktion an. Als Übergabewert müssen wir hier die DatabaseID und die ObjectID angeben.

image 

Wir führen das Script aus und notieren uns die Werte. Danach löschen wir die Tabelle und erstellen die Tabelle erneut, nur diesmal nutzen wir anstatt NEWID() die NEWSEQUENTIALID() Funktion zum erstellen der GUID.

Das Ergebnis ist eindeutig. Die sequenzielle GUID belegt weniger Speicherplatz und benötigt damit auch weniger Seiten. Am deutlichsten ist der Unterschied wohl bei der Fragmentierung zu sehen, hierbei spielt die NEWSEQUENTIALID() ihre ganze Stärke aus. Da die neue GUID immer höher sein muss als die zuvor erzeugte GUID, entsteht in dem Index keine Unordnung und damit auch keine Fragmentierung. Ich habe zum Vergleich mal die Werte eine Primary Key Spalte mit dem Datentyp Integer dazugetan.

image

Wenn man keine absolut eindeutige ID benötigt, so sollte man auf einen Integer zurückgreifen. Dieser lässt den Index nicht so schnell wachsen und fragmentiert diesen auch nur minimal.

Written by Robert Meyer

April 8, 2010 um 15:33

Schreibe einen Kommentar

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s

%d Bloggern gefällt das: