2012-03-15 13 views
18

I nostri dati risiedono in un database di SQL Server 2008, ci saranno molte query e join tra le tabelle. Abbiamo questo argomento all'interno del team, alcuni stanno sostenendo che l'uso dell'identità intera è migliore per le prestazioni, alcuni stanno sostenendo l'uso di guid (identificatore univoco).Identificatore univoco (guid) come chiave primaria nella progettazione del database

Le prestazioni risentono molto male dell'utilizzo di un GUID come chiave primaria?

+2

I maggiori problemi di prestazioni e di frammentazione con un 'UNIQUEIDENTIFIER' arriveranno se si esegue il PK su un indice cluster – Lamak

+0

quindi è importante, è vero che dire sempre usa int piuttosto che guid come pk allora? Perché tutti usano Guid allora? –

+0

dai un'occhiata a questo link per vedere gli effetti sulla frammentazione che usano 'UNIQUEIDENTIFIER' http://www.sqlskills.com/blogs/paul/post/Can-GUID-cluster-keys-cause-non-clustered-index- frammentazione.aspx. D'altra parte, raramente qualcuno usa 'UNIQUEIDENTIFIER' su un indice cluster – Lamak

risposta

31

Una chiave GUID a 128 bit (uniqueidentifier) è ovviamente 4x maggiore di una chiave int a 32 bit. Tuttavia, ci sono alcuni vantaggi chiave:

  • Nessun problema "IDENTITY INSERT" quando si unisce il contenuto
  • Se si utilizza un valore PETTINE invece di NEWSEQUENTIALID(), si ottiene un "libero" INSERT timestamp. È possibile anchedalla chiave primaria in base a un intervallo di data/ora se si desidera con poche chiamate CAST() fantasiose.
  • Sono globalmente unici, che risulta essere abbastanza utile di tanto in tanto.
  • Poiché non è necessario tenere traccia dei contrassegni di acqua alta, il livello BL può assegnare il valore anziché SQL Server, eliminando così il passaggio di SELECT scope_identity() per ottenere la chiave primaria dopo un inserimento.
  • Se è anche lontanamente possibile che si possano avere più di 2 miliardi di record, è necessario utilizzare bigint (64 bit) anziché int. Una volta che lo fai, uniqueidentifier è solo il doppio di un bigint.
  • L'utilizzo di GUID rende più sicuro esporre le chiavi negli URL, ecc. Senza esporsi agli attacchi "guess-the-ID".
  • Tra il modo in cui SQL Server carica le pagine dal disco e il modo in cui i processori ora sono per lo più a 64 bit, solo perché un numero è di 128 bit anziché 32 non significa che richiede più tempo di confronto. L'ultimo test che ho visto ha mostrato che i GUID sono quasi altrettanto veloci.
  • La dimensione dell'indice dipende da quante colonne sono incluse. Anche se i GUID stessi sono più grandi, gli 8 o 12 byte aggiuntivi potrebbero essere insignificanti rispetto alle altre colonne dell'indice.

Alla fine, spremere qualche piccolo vantaggio in termini di prestazioni utilizzando numeri interi potrebbe non valere la pena di perdere i vantaggi di un GUID. Provalo empiricamente e decidi tu stesso.

Personalmente, uso ancora entrambi, a seconda della situazione, ma nel mio caso il fattore decisivo non è mai arrivato alla performance.

+3

+1 per aver menzionato Comb come ho letto che anche questo riduce drasticamente l'indice anche la frammentazione. – Martin

+1

I pettini (ad esempio i GUID sequenziali) possono ridurre la frammentazione, ma su sistemi I/O elevati sembra che i GUID non sequenziali RANDOM possano effettivamente aumentare le prestazioni, in particolare per gli inserti. Il motivo è che le divisioni di pagina sono più economiche della contesa causata dal tentativo di inserire tutto nell'ultima pagina di dati, come con ID sequenziali. Vedi: http://blog.kejser.org/2011/10/05/boosting-insert-speed-by-generating-scalable-keys/ Dipende molto dal sistema sottostante. – Triynko

+1

Guid come PK mal eseguito orribile a inserti se sono in cluster e un PK è di default un indice cluster, il che significa che il motore manterrà la tabella (fisica) ordinata e causando divisioni di tabella e riordino. Non esiste un modo vantaggioso per esporre l'ID negli URL, nessuna differenza se sono stringhe, interi, guidi o altro. I guidi non lo offuscano. – jean

0

Il vantaggio principale dell'utilizzo di GUID è che sono unici in tutto lo spazio e il tempo.

Lo svantaggio principale dell'utilizzo dei GUID come valori chiave è che sono BIG. A 16 byte un pop, sono uno dei più grandi tipi di dati nel server SQL . Gli indici costruiti su GUID saranno più grandi e più lenti degli indici creati su colonne IDENTITY, che sono solitamente inte (4 byte).

Quindi sono una buona soluzione per i casi in cui è necessario unire i dati da diverse fonti

Fonte: http://www.sqlteam.com/article/uniqueidentifier-vs-identity

20

Io personalmente uso INT IDENTITY per la maggior parte delle mie chiavi primarie e di clustering.

è necessario tenere a parte la chiave primaria che è un costrutto logico - si identifica in modo univoco le righe, deve essere unico e stabile e NOT NULL. Un GUID funziona bene anche per una chiave primaria, poiché è garantito che sia unico. Un GUID come chiave primaria è una buona scelta se si utilizza la replica di SQL Server, poiché in tal caso è necessaria comunque una colonna GUID che identifichi univocamente.

La chiave di cluster in SQL Server è un costrutto fisico utilizzato per l'ordinamento fisico dei dati ed è molto più difficile da ottenere. In genere, il Queen of Indexing su SQL Server, Kimberly Tripp, richiede anche una buona chiave di clustering per essere uniqe, stabile, il più stretto possibile e idealmente in continua crescita (tutto ciò che è uno INT IDENTITY).

vederla articoli su indicizzazione qui:

e anche vedere di Jimmy Nilsson The Cost of GUIDs as Primary Key

Un GUID è una orribilmente cattiva scelta per un cluste suoneria, poiché è ampia, totalmente casuale, e quindi porta a una frammentazione dell'indice scadente e prestazioni scadenti. Inoltre, le righe chiave di clustering sono anche memorizzate in ogni singola voce di ogni singolo indice (aggiuntivo) non cluster, quindi si vuole davvero mantenerlo piccolo - GUID è 16 byte vs. INT è 4 byte, e con diversi indici non cluster e diversi milioni di righe, questo fa una grande differenza.

In SQL Server, la chiave primaria è per impostazione predefinita la chiave di clustering, ma non è necessario. È possibile utilizzare facilmente un GUID come chiave primaria NON in cluster e uno INT IDENTITY come chiave di clustering - richiede solo un po 'di consapevolezza.

+0

"Un GUID è una scelta orribile sbagliata per una chiave di clustering" vs "L'ultimo test che ho visto mostra che i GUID sono quasi altrettanto veloci" ... –

+0

@TOMMYWANG: un GUID regolare è ** ORA PROPORRE ** più veloce di INT - vedi [Lo spazio su disco è economico .... NON è il point!] (http://www.sqlskills.com/BLOGS/KIMBERLY/post/Disk-space-is-cheap.aspx) di Kim Tripp, con alcuni test su INT contro GUID –

+0

Generalizzazione: "Un GUID è un scelta orribilmente pessima per una chiave di clustering, poiché è ampia, totalmente casuale, e quindi porta a una frammentazione dell'indice scadente e prestazioni scadenti ". Questa è un'affermazione radicale che è spesso vera. Ma presumi i casi quando non è vero che un dba saprà ignorare questo consiglio? Sfortunatamente l'ambiente in cui viene fornito il consiglio non è chiaro. Capisco che non puoi coprire tutti gli scenari, ma diventa un po 'facile con le iperboliche. Ho visto uno scenario, anche se su un altro DB, che utilizzava GUID partizionati con cluster come MIGLIORE pratica. –

3

Il grande problema con i GUID come chiavi primarie è che causano una massiccia frammentazione della tabella, che può essere un grosso problema di prestazioni (maggiore è la tabella, maggiore è il problema). Anche come chiave per un indice non cluster, causeranno la frammentazione dell'indice.

È possibile attenuare parzialmente il problema impostando un fattore di riempimento appropriato, ma sarà comunque un problema.

La differenza di dimensione non mi disturba più di tanto, tranne che su tabelle con righe altrimenti strette in cui sono richieste anche le scansioni di tabelle. In questi casi, essere in grado di adattare più righe per pagina DB è un vantaggio in termini di prestazioni.

Ci possono essere buoni motivi per utilizzare i GUID, ma c'è anche un costo. Generalmente preferisco INT IDENTITY per le chiavi primarie, ma non evito GUID quando sono una soluzione migliore.

-1

Se i record della tabella del database possono crescere in milioni di record, penso che non sia una buona idea utilizzarlo come chiave primaria.

+1

Non capisco il ragionamento alla base della tua risposta; I GUID sono usati abbastanza frequentemente in molte lingue per rappresentare valori unici. ASP.NET lo utilizza pesantemente nella sua implementazione di sicurezza. – Paul

Problemi correlati