2009-10-19 6 views
20

In un database in cui tutte le chiavi primarie sono GUID, quali sono le differenze/implicazioni e/o pro e contro usando newid() rispetto a newsequentialid() come "valore predefinito o associazione".newid() vs newsequentialid() Quali sono le differenze/pro e contro?

L'unica differenza che conosco è che newid() crea un nuovo GUID casuale rispetto a newsequentialid() crea un nuovo GUID basato sull'ultimo che si trova nella tabella in modo incrementale.

risposta

23

Come ho capito, quando si esegue un inserimento in una riga del DB, verrà inserito in ordine rispetto agli altri PK nella tabella. Con un normale guid, questo potrebbe essere ovunque nel tavolo. Un newsequentialid() verrà sempre aggiunto alla fine della tabella.

Così è migliorata la prestazione degli inserti.

This site spiega le differenze e i parametri tra i due metodi diversi.

Aggiornamento: il post del blog di riferimento è stato spostato. Il link ora si riferisce a un link web.archive.org. Ecco il takeaway chiave:

enter image description here

Più sorprendente è il numero di scritture richieste dalla funzione di sistema NEWID. Questo, insieme alla densità media delle pagine del 69%, è la prova della divisione della pagina causata dalla distribuzione casuale degli inserti a livello foglia. Non appena si riempie una pagina, è necessario suddividerla in 2 pagine del 50% ciascuna per completare l'inserimento. La divisione della pagina non solo ha ridotto la densità delle pagine, ma ha frammentato le pagine di dati in modo piuttosto brutto (c'è una probabilità del 99% che la prossima pagina di dati non sia prossima a quella corrente). Nei nostri test il posto più probabile per una pagina libera richiesta per la suddivisione della pagina è alla fine della tabella, indipendentemente da dove viene inserita la riga. Pertanto, per leggere le righe in ordine, la scansione deve continuare a saltare avanti e indietro tra le pagine divise ampiamente distribuite, quindi la terrificante frammentazione.

--Stefan Delmarco

+0

Eh? Se sono generati in sequenza Come può essere guarnettato che il GUID generato è in realtà univoco, invece di essere qualcosa che assomiglia a un GUID? – Justin

+4

@Justing - Non esiste * garanzia * che un GUID sia unico, è molto probabile che lo sia. –

+1

I collegamenti sono volatili ... Fotia ora 404s il link nella risposta. –

-2

Per quanto ne so, NEWID() genera il GUID in ordine casuale e NEWSEQUENTIALID() genera il GUID in ordine sequenziale. NEWSEQUENTIALID() può essere utilizzato SOLO nella clausola predefinita di una tabella.

+2

Non hai aggiunto nulla a ciò che era già scritto nel domanda. –

1

Dalla mia comprensione, quando l'istanza SQL attiva il GUID NEWSEQUENTIALID viene inizializzato su un valore casuale. Quindi, per tutta la durata della sua operazione, i GUID vengono incrementati sul GUID centrale, NON osservando l'ultimo GUID generato per la tabella.

+1

Il vantaggio di farlo è negli indici. I GUID casuali completi frammentano troppo gli indici, i GUID sequenziali sono utili per le prestazioni di inserimento e indicizzazione. – Todd

+0

[Microsoft states] (https://msdn.microsoft.com/da-dk/library/ms189786.aspx) che è sequenziale rispetto all'ultimo GUID generato dall'ultimo avvio del computer host. –

9

Per quanto riguarda l'uso delle chiavi sequenziali (come con identità, sequenza e NEWSEQUENTIALID) rispetto a quelle non sequenziali (come con NEWID o un generatore di chiavi randomizzato personalizzato), ci sono diversi aspetti da considerare.

A partire dai tasti sequenziali, tutte le righe vanno nella parte destra dell'indice. Quando una pagina è piena, SQL Server alloca una nuova pagina e la riempie. Ciò si traduce in una minore frammentazione dell'indice, che è vantaggiosa per le prestazioni di lettura. Inoltre, gli inserimenti possono essere più veloci quando una singola sessione sta caricando i dati e i dati si trovano su una singola unità o su un numero limitato di unità.

Tuttavia, con sottosistemi di archiviazione di fascia alta con più mandrini, la situazione può essere diversa.Quando si caricano i dati da più sessioni, si finirà con il conflitto della latch di pagina (i latch sono oggetti utilizzati per sincronizzare l'accesso alle pagine del database) rispetto alle pagine più a destra dell'elenco collegato del livello foglia indice. Questo collo di bottiglia impedisce l'utilizzo dell'intero throughput del sottosistema di archiviazione. Si noti che se si decide di utilizzare i tasti sequenziali e si stanno utilizzando quelli numerici, è sempre possibile iniziare con il valore più basso nel tipo per utilizzare l'intero intervallo. Ad esempio, invece di iniziare con 1 in un tipo INT, potresti iniziare con -2,147,483,648.

Considerare chiavi non sequenziali, come quelle casuali generate con NEWID o con una soluzione personalizzata. Quando si tenta di forzare una riga in una pagina già piena, SQL Server esegue una suddivisione classica della pagina: alloca una nuova pagina e sposta metà delle righe dalla pagina originale a quella nuova. Una divisione di pagina ha un costo, oltre a provocare la frammentazione dell'indice. La frammentazione dell'indice può avere un impatto negativo sulle prestazioni delle letture. Tuttavia, in termini di prestazioni di inserimento, se il sottosistema di archiviazione contiene molti assi e si caricano dati da più sessioni, l'ordine casuale può effettivamente essere migliore del sequenziale nonostante le suddivisioni.

Questo perché non esiste un hot spot all'estremità destra dell'indice e si utilizza il throughput disponibile del sottosistema di memoria . Un buon esempio per un benchmark che mostri questa strategia può essere trovato in un blog di Thomas Kejser allo http://blog.kejser.org/2011/10/05/boosting-insert-speed-by-generating-scalable-keys/.

Fonte: Interrogazione Microsoft® SQL Server® 2012 esame 70-461 Training Kit