Domanda

Sto cercando di capire come sequenziale esegue GUID meglio di un guid regolare.

E 'perché con guid regolare, l'indice di utilizzare l'ultimo byte del GUID per ordinare? Dal momento che è casuale causerà un sacco di frammentazione e della pagina divide dal momento che spesso spostare i dati ad un'altra pagina per inserire nuovi dati?

Sequenziale guid sine è sequenziale causerà molto meno divisioni di pagina e la frammentazione?

E 'la mia comprensione corretta?

Se qualcuno può far più luci su questo argomento, io molto apprezzato.

Grazie

EDIT:

Sequenziale guid = NEWSEQUENTIALID (),

regolare guid = NEWID ()

È stato utile?

Soluzione

Hai praticamente detto tutto nella sua interrogazione.

Con un sequenziale GUID / chiave primaria nuove righe verranno aggiunti insieme alla fine del tavolo, che rende le cose belle un facile per il server SQL. In confronto un casuale mezzo di chiave primaria che i nuovi record potrebbero essere inseriti in qualsiasi parte del tavolo - la possibilità dell'ultima pagina per la tabella di essere nella cache è abbastanza probabile (se è lì che tutte le letture stanno andando), tuttavia la possibilità di una pagina a caso nel centro del tavolo essendo nella cache è abbastanza basso, il che significa ulteriore IO è necessaria.

In cima a quello, quando si inserisce righe nella centro del tavolo c'è la possibilità che non c'è abbastanza spazio per inserire la riga in più. Se questo è il caso, allora esigenze del server SQL per eseguire ulteriori costose operazioni di IO, al fine di creare spazio per la cronaca - l'unico modo per evitare questo è di avere lacune sparsi tra i dati per consentire per i record in più da inserire (conosciuto come un fattore di riempimento), che di per sé provoca problemi di prestazioni perché i dati si sviluppa su più pagine e quindi più IO è necessario per accedere l'intera tabella.

Altri suggerimenti

Mi rimetto alla saggezza di Kimberly L. Tripp su questo argomento:

  

Ma, un GUID che non è sequenziale -   come uno che ce l'ha di valori   generato nel client (utilizzando .NET)   O generate dal newid funzione ()   (In SQL Server) può essere una cattiva orribilmente   scelta - soprattutto a causa del   frammentazione che si crea nel   tabella di base ma anche per la sua   dimensione. E 'inutilmente ampia (è 4   volte più larga un'identità int-based   - che può dare 2 miliardi (in realtà, 4 miliardi) righe univoche). E,   se avete bisogno di più di 2 miliardi di te   può sempre andare con un bigint (8 byte   int) e ottenere 263-1 righe.

Per saperne di più: http://www.sqlskills.com/BLOGS/KIMBERLY/post/GUIDs-as-PRIMARY-KEYs-andor-the-clustering-key.aspx#ixzz0wDK6cece

Per visualizzare l'immagine intera util denominato OSTRESS potrebbe essere utilizzato. Per esempio. è possibile creare due tabelle: una con normale GUID come PK, un altro con GUID sequenziale:

-- 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)
);

Poi, con un dato util si esegue un numbero di inserti con la selezione di statistiche su indice di frammentazione:

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

Poi, nel file E: \ incoming \ TMP \ query.out troverete le statistiche. I miei risultati sono i seguenti:

"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       

Come si può vedere con GUID sequenziale generato essendo inserito, indice è molto meno frammentata i conduttori operazione di inserimento a nuova rari allocazione di pagina.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top