Frage

Ich versuche, wie sequentielle guid besser abschneidet als ein normales guid zu verstehen.

Ist es, weil mit regelmäßigen guid, der Index das letzte Byte der GUID zu sortieren verwenden? Da es zufällig ist wird es eine Menge von Fragmentierung und Seitenteilungen verursachen, da es oft Daten auf eine andere Seite verschieben werden neue Daten einfügen?

Sequential guid Sinus ist es sequenzielle es wird dazu führen, viel weniger Seitenteilungen und Fragmentierung?

Ist mein Verständnis richtig?

Wenn jemand mehr Licht auf das Thema werfen kann, werde ich sehr geschätzt.

Danke

EDIT:

Sequential guid = NEWSEQUENTIALID ()

Regular guid = NEWID ()

War es hilfreich?

Lösung

Sie haben gesagt, so ziemlich alles in Frage.

Mit einem sequenziellen GUID / Primärschlüssel neue Zeilen am Ende der Tabelle addiert werden, die Dinge schön ein einfach für SQL Server macht. Im Vergleich ein Zufallsprimärschlüssel bedeutet, dass neue Datensätze überall in der Tabelle eingefügt werden könnten - die Chance auf der letzten Seite der Tabelle im Cache zu sein, ist ziemlich wahrscheinlich (wenn das, wo alle die gehen lesen), aber die Chance, eine zufällige Seite in der Mitte der Tabelle im Cache ist ziemlich niedrig ist, zusätzliche IO Bedeutung erforderlich ist.

Hinzu kommt, dass, wenn Zeilen in die Mitte des Tisches Einsetzen gibt es die Chance, dass es nicht genug Platz ist, um die zusätzliche Zeile einzufügen. Wenn dies der Fall ist, dann SQL Server braucht, ist zusätzliche teure IO-Operationen durchzuführen, um Platz für den Datensatz zu erstellen - den einzigen Weg, dies zu vermeiden ist es, Lücken zwischen den Daten verstreut zu haben, um zusätzliche Datensätze zu ermöglichen (auch bekannt als ein eingefügt werden Füllfaktor), die an sich verursacht Leistungsprobleme, weil die Daten verteilt über mehrere Seiten ist und so mehr IO erforderlich, um die gesamte Tabelle zugreifen zu können.

Andere Tipps

ich aufschieben zu diesem Thema Kimberly L. Tripp Weisheit:

  

Aber eine GUID, die nicht sequentiell ist -   wie einer, der es Werte hat   erzeugt in dem Client (unter Verwendung von .NET)   Oder durch die newid erzeugt () -Funktion   (In SQL Server) kann ein schrecklich schlecht sein   Wahl - vor allem wegen der   Fragmentierung, die es in der schafft   Basistabelle, sondern auch wegen seines   Größe. Es ist unnötig breit (es ist 4   mal breiter als eine int-basierte Identität   - das können Sie 2 Milliarden (wirklich, 4 Milliarden) eindeutige Zeilen). Und,   wenn Sie brauchen mehr als 2 Milliarden Sie   kann immer mit einem Bigint (8-Byte gehen   int) und 263-1 Reihen erhalten.

Lesen Sie mehr über: http://www.sqlskills.com/BLOGS/KIMBERLY/post/GUIDs-as-PRIMARY-KEYs-andor-the-clustering-key.aspx#ixzz0wDK6cece

Um das ganze Bild visualisieren util Namen OSTRESS verwendet werden könnten. Z.B. Sie können zwei Tabellen erstellen: eine mit normalen GUID als PK, eine andere mit sequentieller GUID:

-- normal one
CREATE TABLE dbo.YourTable(
   [id] [uniqueidentifier] NOT NULL,
   CONSTRAINT [PK_YourTable] PRIMARY KEY NONCLUSTERED (id)
);
-- sequential one
CREATE TABLE dbo.YourTableSeq(
   [id] [uniqueidentifier] NOT NULL CONSTRAINT [df_yourtable_id]  DEFAULT (newsequentialid()),
   CONSTRAINT [PK_YourTableSeq] PRIMARY KEY NONCLUSTERED (id)
);

Dann mit einem gegebenen util Sie eine numbero von Einsätzen mit einer Auswahl an Statistiken über Index-Fragmentierung ausführen:

ostress -Slocalhost -E -dYourDB -Q"INSERT INTO dbo.YourTable VALUES (NEWID()); SELECT count(*) AS Cnt FROM dbo.YourTable; SELECT AVG_FRAGMENTATION_IN_PERCENT AS AvgPageFragmentation, PAGE_COUNT AS PageCounts FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, N'LIMITED') DPS INNER JOIN sysindexes SI ON DPS.OBJECT_ID = SI.ID AND DPS.INDEX_ID = SI.INDID WHERE SI.NAME = 'PK_YourTable';" -oE:\incoming\TMP\ -n1 -r10000

ostress -Slocalhost -E -dYourDB -Q"INSERT INTO dbo.YourTableSeq DEFAULT VALUES; SELECT count(*) AS Cnt FROM dbo.YourTableSeq; SELECT AVG_FRAGMENTATION_IN_PERCENT AS AvgPageFragmentation, PAGE_COUNT AS PageCounts FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, N'LIMITED') DPS INNER JOIN sysindexes SI ON DPS.OBJECT_ID = SI.ID AND DPS.INDEX_ID = SI.INDID WHERE SI.NAME = 'PK_YourTableSeq';" -oE:\incoming\TMP\ -n1 -r10000

Dann in der Datei E: \ incoming \ TMP \ query.out werden Sie Ihre Statistiken finden. Meine Ergebnisse sind:

"Normal" GUID:
Records    AvgPageFragmentation     PageCounts           
---------------------------------------------- 
1000       87.5                     8                    
2000       93.75                    16                   
3000       96.15384615384616        26                   
4000       96.875                   32                   
5000       96.969696969696969       33                   
10000      98.571428571428584       70                   


Sequential GUID:
Records    AvgPageFragmentation     PageCounts           
---------------------------------------------- 
1000       83.333333333333343       6                    
2000       63.636363636363633       11                   
3000       41.17647058823529        17                   
4000       31.818181818181817       22                   
5000       25.0                     28                   
10000      12.727272727272727       55       

Wie Sie mit sequentiell erzeugt GUID wird eingefügt sehen können, wird der Index sehr viel weniger fragmentiert wie die Einfügeoperation führt zu neuen Seitenzuordnungs- seltener.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top