2009-09-17 11 views
9

Ultimamente, ho fatto qualche lettura su indici di tutti i tipi e il consiglio principale è di mettere l'indice cluster sulla chiave primaria della tabella, ma cosa succede se la chiave primaria non è effettivamente usata in una query (tramite una selezione o aderire) ed è solo per scopi puramente relazionali, quindi in questo caso non viene contestato. Esempio, dire che ho una tabella car_parts e contiene 3 colonne, car_part_id, car_part_no e car_part_title. car_part_id è la colonna di identità della chiave primaria univoca. In questo caso, anche lo car_part_no è unico ed è probabilmente car_part_title. car_part_no è ciò che è più richiesto, quindi non ha senso inserire l'indice cluster su quella colonna invece di car_part_id? Le basi della domanda è quale colonna dovrebbe avere effettivamente l'indice cluster poiché è consentito solo uno di essi?In quale colonna deve essere inserito l'indice cluster?

+1

È molto bello che ti poni queste domande. Fare la scelta giusta ora ha un * enorme * impatto sulle tue prestazioni e sulla sciabilità in seguito. –

+0

La maggior parte delle chiavi primarie che esistono "puramente per scopi relazionali" riflettono un'idea errata sul modello relazionale. Se non ci sono chiavi esterne che fanno riferimento a una chiave primaria, è probabile che un modello relazionale abbia scelto una chiave primaria diversa. –

risposta

8

Un indice, in cluster o non clustato, può essere utilizzato da Query Optimizer se e solo se viene filtrata la chiave più a sinistra dell'indice. Pertanto, se si definisce un indice su colonne (A, B, C), una condizione WHERE su [email protected], su [email protected] o su [email protected] AND [email protected] non sfrutterà completamente l'indice (vedere nota). Questo vale anche per le condizioni di adesione.Qualsiasi filtro WHERE che include A considererà l'indice: [email protected] o [email protected] AND [email protected] o [email protected] AND [email protected] o [email protected] AND [email protected] AND [email protected].

Quindi nel tuo esempio, se si effettua l'indice clustred sul part_no come la chiave più a sinistra, poi una query alla ricerca di una specifica part_id sarà non utilizzare l'indice e un indice non cluster separato deve esistere part-id.

Ora sulla questione quale dei molti indici dovrebbe essere il cluster uno. Se si dispone di diversi modelli di query che sono circa la stessa importanza e frequenza e si contraddicono a vicenda sui termini delle chiavi necessarie (ad esempio, frequenti richieste di siapart_no o part_id.) Poi si prende altri fattori in considerazione:

  • larghezza: la chiave di indice cluster viene utilizzata come chiave di ricerca da tutti gli indici non cluster. Quindi, se scegli una chiave ampia (ad esempio due colonne unidentificatore), ingrandisci tutti gli altri indici, consumando così più spazio, generando più IO e rallentando tutto. Quindi, tra le buone chiavi uguali da un punto di vista di lettura, scegliere quello più stretto come cluster e rendere quelle più grandi non raggruppate.
  • contention: se si dispone di pattern specifici di insert e delete, provare a separarli fisicamente in modo che si verifichino su diverse parti dell'indice cluster. Per esempio. se la tabella agisce come una coda con tutti gli inserimenti a una estremità logica e tutti si eliminano dall'altra estremità logica, provare a strutturare l'indice cluster in modo che l'ordine fisico corrisponda a questo ordine logico (ad esempio, ordine enqueue).
  • partizionamento: se la tabella è molto grande e si prevede di distribuire il partioning, la chiave di partizionamento deve essere l'indice cluster. Un tipico esempio sono i dati storici che vengono archiviati utilizzando uno schema di partizionamento della finestra scorrevole. Anche se le entità hanno una chiave primaria logica come "entity_id", l'indice clustato viene eseguito da una colonna datetime che viene utilizzata anche per la funzione di partizionamento.
  • stabilità: una chiave che cambia spesso è un candidato povero per una chiave cluster come ogni aggiornamento del valore della chiave cluster e forza tutti indici non cluster per aggiornare la chiave di ricerca che contengono. Poiché anche un aggiornamento di una chiave in cluster probabilmente trasferirà il record in una pagina diversa, può causare la frammentazione dell'indice cluster.

Nota: non pienamente leva come a volte il motore sceglierà un indice non cluster per scansione anziché l'indice cluster, semplicemente perché è più stretta e ha meno pagine per la scansione in tal modo. Nel mio esempio se hai un indice su (A, B, C) e un filtro WHERE su [email protected] e sui progetti di query C, l'indice sarà probabilmente usato ma non come ricerca, come una scansione, perché è ancora più veloce di un scansione completa in cluster (meno pagine).

1

L'indice cluster dovrebbe andare sulla colonna che sarà la più interrogata. Ciò include i join, poiché un join deve accedere alla tabella come una query diretta e trovare le righe indicate.

È possibile ricostruire gli indici in un secondo momento se l'applicazione cambia e si scopre che è necessario ottimizzare una tabella con una struttura di indice diversa.

Alcune linee guida aggiuntive per decidere su quale cluster il tuo tavolo può essere trovato su MSDN qui: Clustered Index Design Guidelines.

+0

quindi suppongo che il mio post abbia senso allora. Utilizzerebbe un inner join sul numero di chiavi primarie come query sulla colonna anche se non è incluso nell'elenco di selezione. – Xaisoft

+0

... ricordando che l'interrogazione non significa necessariamente l'utilizzo come criterio da parte dell'utente finale nelle sue ricerche, ma anche l'uso in JOIN e varie subquery [implicite/dimenticate]. – mjv

+0

@ mjv, hai letto nella mia mente. – Xaisoft

2

Tenere presente i modelli di utilizzo; Se stai quasi sempre interrogando il DB su car_part_no, probabilmente sarebbe utile che fosse raggruppato in quella colonna.

Tuttavia, non dimenticare di join; Se ti unisci più spesso alla tabella e il join utilizza il campo car_part_id, hai una buona ragione per mantenere il cluster su car_part_id.

Un'altra cosa da tenere a mente (meno in questo caso, ma in generale quando si considerano gli indici cluster) è che l'indice cluster apparirà implicitamente in ogni altro indice sulla tabella; Ad esempio, se indicassi car_part_title, tale indice includerà implicitamente anche car_part_id. Ciò può influire sul fatto che un indice copra una query e influisce anche sulla quantità di spazio su disco che l'indice impiegherà (che influisce sull'utilizzo della memoria, ecc.).

4

Gli indici clusterizzati sono buoni quando si interrogano intervalli di dati. Ad esempio

SELECT * FROM theTable WHERE age BETWEEN 10 AND 20 

L'indice cluster organizza le righe nell'ordine specifico sul disco del computer. Ecco perché le righe con l'età = 10 sarà uno accanto all'altro, e dopo di loro ci saranno righe con età = 11, etc.

Se avete esatto selezionare, in questo modo:

SELECT * FROM theTable WHERE age = 20 

la non anche l'indice ristretto è buono. Non riorganizza i dati sul disco del tuo computer, ma crea un albero speciale con un puntatore alle righe che ti servono.

Quindi dipende fortemente dal tipo di query che si esegue.

4

Kimberly Tripp è sempre una delle migliori fonti di approfondimento sull'indicizzazione.

vedere il suo post sul blog "Ever-increasing clustering key - the Clustered Index Debate - again!" in cui lei elenca chiaramente e spiega i principali requisiti per una buona chiave di clustering - ha bisogno di essere:

  • unico
  • stretta
  • Static

e meglio di tutti, se è possibile gestire:

  • sempre crescente

Prendendo in considerazione tutto questo, un INT IDENTITY (o BIGINT IDENTITY se si ha realmente bisogno di più di 2 miliardi di righe) funziona a essere la scelta migliore nella stragrande maggioranza dei casi.

Una cosa che molte persone non capiscono (e quindi non prendono in considerazione quando fanno la loro scelta) è il fatto che la chiave di clustering (tutte le colonne che compongono l'indice cluster) sarà aggiunta a ogni singola voce di indice per ogni singolo indice non raggruppato sul tuo tavolo - quindi il requisito "stretto" diventa più importante!

Inoltre, poiché la chiave di clustering viene utilizzata per le ricerche nei segnalibri (cercando la riga di dati effettiva quando viene trovata una riga in un indice non in cluster), anche il requisito "univoco" diventa molto importante. È così importante, infatti, che se si sceglie una (o più) colonna (i) che è/non è garantita la sua unicità, SQL Server aggiungerà un uniquefier a 4 byte a ciascuna riga -> così facendo ognuno dei tasti di indice cluster più larghi; sicuramente NON una buona cosa.

Marc

Problemi correlati