2010-02-07 8 views
13

Io non sono un DBA ("! Good", ti verrà pensando in un momento.)Raggruppa l'indice sulla colonna datetime sempre crescente sulla tabella di registrazione?

Ho una tabella dei dati di registrazione con queste caratteristiche e modelli di utilizzo:

  • Una colonna datetime per la memorizzazione di timestamp di registro il cui valore è sempre crescente e principalmente (ma solo per lo più) unico
  • Inserimenti frequenti (ad esempio, una dozzina di minuti), solo alla fine dell'intervallo di data/ora (nuovi dati registrati
  • Elimina raramente, alla rinfusa, fr om il inizio del campo timestamp (vecchi dati che vengono cancellati)
  • Nessun aggiornamento a tutti i
  • seleziona frequenti-ish che utilizzano la colonna timestamp come criterio primario, insieme con criteri secondari su altre colonne
  • Seleziona infrequenti utilizzando altre colonne come i criteri (e non tra cui la colonna timestamp)
  • Una buona quantità di dati, ma in nessun posto vicino abbastanza che mi preoccupa molto di spazio di archiviazione

Inoltre, attualmente esiste una finestra di manutenzione giornaliera durante la quale è possibile eseguire l'ottimizzazione della tabella.

Francamente non mi aspetto che questa tabella sfidi il server su cui si accederà anche se indicizzo male un po ', ma tuttavia mi è sembrata una buona opportunità per chiedere un input sugli indici cluster di SQL Server.

So che gli indici cluster determinano la memorizzazione dei dati della tabella effettiva (i dati sono memorizzati nei nodi foglia dell'indice stesso) e che gli indici non in cluster sono indicatori separati nei dati. Quindi, in termini di query, un indice cluster sarà più veloce di un indice non in cluster - una volta che abbiamo trovato il valore dell'indice, i dati sono proprio lì. Ci sono costi per l'inserimento e l'eliminazione (e ovviamente un aggiornamento che modifica il valore della colonna dell'indice clustered sarebbe particolarmente costoso).

Ma ho letto in this answer che elimina gli spazi vuoti che non vengono ripuliti fino a/a meno che l'indice non venga ricostruito.

Tutto questo mi fa pensare che avrei dovuto:

  • Mettere un indice cluster sulla colonna timestamp con un fattore di riempimento 100%
  • indici non cluster mettere su qualsiasi altra colonna che potrebbe essere utilizzato come criterio in una query che non coinvolge anche la colonna in cluster (che può essere qualsiasi di esse nel mio caso)
  • Pianificare le eliminazioni di massa che si verificano durante l'intervallo di manutenzione giornaliera
  • Pianificare una ricostruzione del cluster indice che si verifica immediatamente dopo il bulk de Lete
  • rilassarsi e di più

Am I di base selvaggiamente fuori là? Devo ricostruire frequentemente l'indice in questo modo per evitare un sacco di spazio sprecato? Ci sono altre cose ovvie (a un DBA) che dovrei fare?

Grazie in anticipo.

+2

Suggerisco solo di fare attenzione all'uso di "timestamp" per descrivere una colonna datetime. In SQL Server, il termine "timestamp" è stato vittima di essere assegnato a un tipo di dati che non ha nulla a che fare con la data o l'ora, chiamato ROWVERSION. Dato che questo può sempre innescare confusione, abituarmi ad evitare questo termine, anche quando intendi davvero una colonna ROWVERSION. Purtroppo gli stessi strumenti di SQL Server non lo incoraggiano davvero, infatti quando crei una colonna ROWVERSION, lo script finisce per mostrarti TIMESTAMP.

+0

@Aaron: Doh! Buon punto, grazie. Sulla base di ciò stavo per tornare indietro e modificare, ma si è trasformato in un disastro. Spero che grazie al tuo commento le persone non lo leggeranno male. –

risposta

3

Concordo con l'inserimento dell'indice cluster sulla colonna timestamp. La mia interrogazione sarebbe sul fillfactor: il 100% offre le migliori prestazioni di lettura a scapito delle prestazioni di scrittura. potresti essere ferito dalla divisione delle pagine. La scelta di un fattore di riempimento inferiore ritarderà la divisione delle pagine a scapito delle prestazioni di lettura, pertanto è un ottimo bilanciamento per ottenere il meglio per la propria situazione.

Dopo che il bulk ha eliminato, vale la pena ricostruire gli indici e aggiornare le statistiche. Ciò non solo mantiene le prestazioni ma reimposta anche gli indici sul fillfactor specificato.

Infine, sì inserire indici non cluster su altre colonne appropriate, ma solo quelli che sono molto selezionati, ad esempio non campi bit. Ma ricorda più indici, più questo influisce sulle prestazioni di scrittura

+0

Grazie. Il mio pensiero sul fattore di riempimento è che inserirò sempre lo stesso valore del mio ultimo inserto (raramente) o un valore più alto, mai * inserendo * nella sequenza. Quindi lasciare spazio per l'aggiunta di record alle pagine indice esistenti sembra inutile - per la mia comprensione incompleta delle cose. :-) –

+0

Sì, è un buon punto. Stavo pensando comunque ad un fillfactor molto alto. Penso che tu sia in the money con la tua ricerca. Ma monitoralo ancora, fai qualche test. A proposito, è possibile monitorare le suddivisioni di pagina in perfmon. – AdaTheDev

3

Ci sono due modi "best practice" per indicizzare un alto traffico tabella di registrazione:

  1. una colonna integer identità come chiave primaria Colum
  2. un uniqueidentifier cluster come chiave primaria, con DEFAULT NEWSEQUENTIALID()

Entrambi i metodi consentono a SQL Server di espandere la tabella in modo efficiente, poiché sa che l'albero dell'indice crescerà in una determinata direzione.

Non aggiungerei altri indici sulla tabella o pianificare le ricostruzioni dell'indice, a meno che non ci sia un problema di prestazioni specifico.

+1

E nota l'impostazione predefinita "NewSequentialID() .I identificatori univoci che non sono sequenziali uccideranno le prestazioni su tabelle con traffico di inserimenti pesanti .In ogni caso, a meno che tu non abbia una specifica esigenza di identificatori univoci, vai con un'identità intera –

+1

Interessante, grazie Ho intenzione di interrogare questa tabella sulla base di tale timestamp abbastanza frequentemente, e * mai * con qualsiasi tipo di chiave intera univoca. Poiché il timestamp è monotono (anche se non perfettamente unico), perché non è una scelta migliore per l'indice cluster? Voglio dire, mi aspetto che il timestamp sia unico almeno per il 95% delle volte, non come la registrazione di hit web dove potrebbe facilmente essere molto più basso di quello. (+1, btw, per il "don" t ottimizzare prematuramente "promemoria") –

+1

SQL Server non sa che è possibile immettere solo date maggiori in una colonna di data e ora, è possibile inserire una data nel passato, rendendo più difficile mantenere l'indice riempito in modo ottimale – Andomar

0

La risposta ovvia dipende da come lo si interroga. Il punto dell'indice è di ridurre la quantità di confronti quando si selezionano i dati. L'indice cluster aiuta quando si considerano i dati che verranno caricati insieme e il fattore di blocco della memoria (è possibile caricare un gruppo di dati in un blocco di 64k con una lettura). Se includi un ID e un datetime come chiave primaria, ma non li utilizzi nei criteri di selezione, non faranno altro che ostacolare le tue prestazioni. Questo è il motivo per cui le persone di solito rilasciano indici su inserimenti di massa prima di caricare i dati.

+0

Grazie.Penso di aver indicato come stavo per interrogarlo: molto sulla base della colonna timestamp, occasionalmente su altre colonne non in combinazione con il timestamp. –

+1

C'è una combo che non sto attraversando bene (il mio male): è meglio includere tutti i campi di ricerca nell'indice come un indice composito. Anche l'ordine dei campi è importante. Ovviamente il punto della tua domanda, ma c'è un trucco elegante per abbinare i campi di ricerca e quali campi vanno al tuo indice. –

+0

Grazie. Penso che tu stia parlando di situazioni in cui posso soddisfare la query direttamente da un indice composto senza dover quindi cercare i dati "reali". Punto valido, ma non necessario in questo caso; il tipo di query che faremo ci porterà sempre ai dati principali. –

5

Contrariamente a quanto molti credono, avere un buon indice cluster su un tavolo può effettivamente rendere più veloci le operazioni come INSERT - sì, più veloce!

Scopri il blog post seminale The Clustered Index Debate Continues.... di Kimberly Tripp - l'ultima regina dell'indicizzazione.

Accenna (circa a metà di questo articolo):

inserti sono più veloci in un cluster tavolo (ma solo nel "giusto" tabella cluster) che, rispetto a un cumulo . Il problema principale qui è che le ricerche in IAM/PFS per determinare la posizione di inserimento in un heap sono più lenta in una tabella cluster (dove è nota la posizione di inserimento, definita dalla chiave cluster). Gli inserti sono più veloci se inseriti in una tabella dove l'ordine è definito (CL) e dove quell'ordine è in costante aumento.

Il punto cruciale è: solo con il diritto indice cluster si sarà in grado di raccogliere i frutti - quando un indice cluster è unico, stretto, stabile e in modo ottimale sempre crescente. Questo è meglio servito con una colonna INT IDENTITY.

Kimberly Tripp ha anche un grande articolo su come scegliere il miglior chiave di clustering possibile per le tabelle, e quali criteri dovrebbe compiere - vedere il suo post intitolato Ever-increasing clustering key - the Clustered Index Debate..........again!

Se si dispone di una colonna di - per esempio una chiave primaria surrogata: usa quella per la tua chiave di clustering e dovresti vedere prestazioni molto buone sul tuo tavolo - anche su molti INSERT.

+0

Lettura di grande valore, grazie! –

Problemi correlati