Domanda

Fino ad ora sto usando C# "Guid = Guid.NewGuid();" metodo per generare un ID univoco che può essere memorizzato come il campo ID in alcune delle mie tabelle di database SQL Server utilizzando Linq to SQL.Sono stato informato che per motivi di indicizzazione, utilizzando un GUID è una cattiva idea, e che dovrei usare un incremento automatico invece.L'uso a lungo la velocità delle transazioni del database?Se è così, come faccio a generare ID univoco che sono di tipo Long?

Saluti,

È stato utile?

Soluzione

Entrambe hanno vantaggi e svantaggi, dipende interamente da come li si usa che conta.

Destra fuori del blocco, se avete bisogno di identificatori che possono lavorare tra diverse banche dati, è necessario GUID. Ci sono alcuni trucchi con lunghi (assegnando manualmente ogni database un diverso seme / incremento), ma questi non scala bene.

Per quanto riguarda l'indicizzazione va, Long darà prestazioni molto migliori di inserimento se l'indice è di tipo cluster (da chiavi primarie predefiniti sono raggruppati, ma questo può essere modificato per la vostra tavola), dal momento che il tavolo non ha bisogno di essere riorganizzata dopo ogni inserire.

Per quanto inserti simultanei concerne tuttavia, Long (identità) colonne sarà più lento GUID - generazione colonna Identity richiede una serie di blocchi esclusivi per garantire che solo una riga ottiene il numero sequenziale successiva. In un ambiente con molti utenti di inserire più righe per tutto il tempo, questo può essere un calo di prestazioni. generazione GUID in questa situazione è più veloce.

Stoccaggio saggio, un GUID occupa il doppio dello spazio di un lungo (8 byte vs 16). Tuttavia essa dipende dalla dimensione globale della vostra riga se 8 byte sta andando a fare una notevole differenza in quanti record inserirsi in una foglia, e quindi il numero di foglie tirato dal disco durante una richiesta media.

Altri suggerimenti

Un lungo (grande int in SQL Server) è di 8 byte e un GUID è di 16 byte, quindi si è dimezzare il numero del server SQL byte deve confrontare quando si fa uno sguardo in su.

Per la generazione di un lungo, uso IDENTITY (1,1) quando si crea il campo del database.

quindi o utilizzando CREATE TABLE o ALTER tabella:

Field_NAME BIGINT NOT NULL PRIMARY KEY IDENTITY(1,1)

Vedere i commenti per la pubblicazione di LINQ to SQL

La "regina di indicizzazione" - Kim Tripp - dice praticamente tutto nella sua indicizzazione post del blog:

In sostanza, le sue migliori pratiche sono: una chiave di clustering ottimale dovrebbe essere:

  • Unique
  • piccolo
  • stabile (immutabile)
  • sempre crescente

GUID violano la "piccola" e "sempre crescente" e non sono quindi ottimale.

PLUS: tutte le chiavi di clustering verranno aggiunti ad ogni singola voce in ogni singolo indice non cluster (come la ricerca per trovare in realtà il record nel database), in tal modo si vuole fare loro il più piccolo possibile (INT = 4 byte vs. GUID = 16 byte). Se si dispone di centinaia di milioni di righe e di diversi indici non in cluster, scegliendo un INT o BIGINT nel corso di un GUID può fare una grande differenza -. Anche solo spazio-saggio

Marc

Utilizzare GUID quando è necessario considerare import / export a più database. GUID sono spesso più facili da usare rispetto colonne che specificano l'attributo di identità quando si lavora con un set di dati di molteplici relazioni del bambino. questo è perché è possibile generare in modo casuale GUID nel codice in uno stato disconnesso dal database, e quindi inviare tutte le modifiche in una sola volta. Quando GUID vengono generati correttamente, sono insainely difficile da duplicare per caso. Con le colonne di identità, spesso si devono fare un inserto intial di una riga padre e di query per la sua nuova identità prima di aggiungere i dati del bambino. È quindi necessario aggiornare tutti i record figlio con la nuova identità genitore prima di commettere al database. Lo stesso vale per i nipoti e così via fino alla gerarchia. Esso si basa fino a un sacco di lavoro che sembra inutile e banale. Si può fare qualcosa di simile a GUID da ritornassi con numeri interi casuali senza la specifica identità, ma la probabilità di collisione è notevolmente aumentato come si inseriscono più record nel corso del tempo. (Guid.NewGuid () è simile a un Int128 casuale - che non esiste ancora).

Io uso Byte (TinyInt), Int16 (SmallInt), Int32 / UInt16 (Int), Int64 / UInt32 (BigInt) per le piccole liste di ricerca che non cambiano o di dati che non replica tra più database. (permessi, applicazione di configurazione, i nomi dei colori, ecc.)

Mi immagino l'indicizzazione vuole solo il tempo per interrogare contro a prescindere se si utilizza un GUID o un lungo. Di solito ci sono altri campi in tabelle indicizzati che sono più grandi di 128 bit (comunque nomi utente in una tabella utente per esempio). La differenza tra GUID e interi è la dimensione dell'indice nella memoria, così come il tempo popolamento e ricostruzione degli indici. La maggior parte delle transazioni del database è spesso leggendo. La scrittura è minimo. Concentratevi su come ottimizzare la lettura dal database prima, in quanto sono di solito fatte di tabelle unite che non sono stati ottimizzati correttamente, paging improprio o indici mancanti.

Come con qualsiasi cosa, la cosa migliore da fare è quello di dimostrare il tuo punto. creare un database di prova con due tavoli. Uno con una chiave primaria di interi / Longs, e l'altro con un GUID. Popolare ciascuno con N-milioni di righe. Moniter le prestazioni di ciascuno durante le operazioni CRUD (creazione, lettura, aggiornamento, cancellazione). Si può scoprire che si ha un calo di prestazioni, ma insignificante.

I server spesso eseguite su scatole senza il debug di ambienti e di altre applicazioni riprendendo CPU, memoria e I / O del disco rigido (in particolare con il RAID). Un ambiente di sviluppo si dà solo un'idea di prestazioni.

Si può discutere GUID o identità di tutti i giorni.Io preferisco il database per generare il valore unico con un'identità.Se si uniscono i dati da più database, aggiungere un'altra colonna (per identificare il database di origine, forse un tinyint o smallint) e la forma di una chiave primaria composta.

Se vai con un'identità, essere sicuri di scegliere il giusto tipo di dati, basato sul numero di tasti si generano:

bigint - 8 Bytes - max positive value: 9,223,372,036,854,775,807  
int    - 4 Bytes - max positive value:             2,147,483,647

Nota "numero di tasti" è diverso dal numero di righe.Se si tratta di aggiungere e mantenere le righe, si potrebbe scoprire che un INT è sufficiente, con oltre 2 miliardi di chiavi univoche.Scommetto che la tua tabella non ottenere un grande.Tuttavia, se si dispone di un elevato volume di tabella in cui si tiene l'aggiunta e la rimozione di righe, numero di riga può essere basso, ma si passa attraverso i tasti veloci.Si dovrebbe fare un po ' di calcoli per vedere come log sarebbe quello di passare attraverso il INTs 2 miliardi di chiavi.Se non utilizzarli in qualunque momento presto andare con INT, altrimenti il doppio della dimensione della chiave e vai con BIGINT.

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