Indici multipli vs indici a più colonne


646

Ho appena aggiunto un indice a una tabella in SQL Server 2005 e mi ha fatto pensare. Qual è la differenza tra la creazione di 1 indice e la definizione di più colonne rispetto all'avere 1 indice per colonna che si desidera indicizzare.

Ci sono alcuni motivi per cui uno dovrebbe essere usato sull'altro?

Per esempio

Create NonClustered Index IX_IndexName On TableName
(Column1 Asc, Column2 Asc, Column3 Asc)

Contro

Create NonClustered Index IX_IndexName1 On TableName
(Column1 Asc)

Create NonClustered Index IX_IndexName2 On TableName
(Column2 Asc)

Create NonClustered Index IX_IndexName3 On TableName
(Column3 Asc)

Risposte:


319

Sono d'accordo con Cade Roux .

Questo articolo dovrebbe portarti sulla strada giusta:

Una cosa da notare, gli indici cluster dovrebbero avere una chiave univoca (una colonna di identità che consiglierei) come prima colonna. Fondamentalmente aiuta i tuoi dati a inserirsi alla fine dell'indice e non causa molte divisioni di I / O del disco e pagine.

In secondo luogo, se stai creando altri indici sui tuoi dati e questi sono costruiti in modo intelligente, verranno riutilizzati.

ad esempio, immagina di cercare una tabella su tre colonne

stato, contea, CAP.

  • a volte cerchi solo per stato.
  • a volte cerchi per stato e contea.
  • cerchi frequentemente per stato, contea, CAP.

Quindi un indice con stato, contea, zip. verrà utilizzato in tutte e tre queste ricerche.

Se si esegue una ricerca per zip da solo abbastanza, l'indice sopra non verrà utilizzato (comunque da SQL Server) poiché zip è la terza parte di tale indice e Query Optimizer non vedrà tale indice come utile.

È quindi possibile creare un indice solo su Zip da utilizzare in questa istanza.

A proposito, possiamo sfruttare il fatto che con l'indicizzazione multi-colonna la prima colonna dell'indice è sempre utilizzabile per la ricerca e quando si cerca solo per 'stato' è efficiente ma non efficiente come l'indice a colonna singola su 'stato '

Immagino che la risposta che stai cercando sia che dipende dalle clausole where delle tue query usate di frequente e anche dal tuo gruppo per quello.

L'articolo aiuterà molto. :-)


2
Quindi la cosa migliore da fare sarebbe definire un indice per stato, contea e zip oltre a un indice individuale per ogni colonna?
Maxim Zaslavsky,

12
@jball Mi sto perdendo qualcosa qui? Sembra che l'articolo riguardi principalmente le differenze tra i limiti di versione di SQL Server. L'articolo potrebbe essere stato spostato?
Ian R. O'Brien,

@Ian sembra che qualcosa sia andato perduto nei prossimi 3 anni da quando ho risolto il link originale da ora più di 4 anni fa. Posso dirti che il post sul blog ha il titolo corretto come era collegato da evilhomer, ma sembra che i blog di follow-up della serie non siano più facilmente reperibili da quel primo post. Dovrai cercare l'archivio del blog di Kimberly per vedere se riesci a trovare gli altri della serie.
jball

1
1) "Fondamentalmente [Indice cluster con la colonna IDENTITY come primo] aiuta l'inserimento dei dati alla fine dell'indice" è corretto. "e non causare un sacco di I / O del disco e suddivisioni di pagina" è totalmente falso in un sistema multiutente. La verità è che garantisce un'elevata contesa (bassa concorrenza) in un sistema multiutente. 2) L'indice cluster dovrebbe essere una chiave relazionale, vale a dire. non un IDENTITY, GUID, etc. 3) "Quindi un indice con stato, contea, zip. Verrà utilizzato in tutte e tre queste ricerche." è falso e contraddice "la prima colonna è utilizzabile". Il 2 ° e il secondo punto dell'indice non sono utilizzabili per la ricerca.
PerformanceDBA

81

Sì. Ti consiglio di leggere gli articoli di Kimberly Tripp sull'indicizzazione .

Se un indice è "coprente", non è necessario utilizzare altro che l'indice. In SQL Server 2005 è inoltre possibile aggiungere all'indice colonne aggiuntive che non fanno parte della chiave, in grado di eliminare i viaggi nel resto della riga.

Avere più indici, ognuno su una singola colonna può significare che viene utilizzato solo un indice: dovrai fare riferimento al piano di esecuzione per vedere quali effetti offrono diversi schemi di indicizzazione.

È inoltre possibile utilizzare la procedura guidata di ottimizzazione per determinare quali indici farebbero funzionare al meglio una determinata query o un carico di lavoro.


7
Kimberly Tripp sa di cosa sta parlando. Stavo parlando di lei e lei conosce queste cose a rovescio. Ottimo consiglio
evilhomer,

@CadeRoux Se la maggior parte delle volte la mia clausola where ha 2 colonne nella relazione '&', sarà meglio avere un indice multi-colonna su di esse o un indice a colonna singola su entrambe
È una trappola

2
@RachitGupta Un indice con entrambe le colonne
Cade Roux

40

L'indice multi-colonna può essere utilizzato per le query che fanno riferimento a tutte le colonne:

SELECT *
FROM TableName
WHERE Column1=1 AND Column2=2 AND Column3=3

Questo può essere cercato direttamente usando l'indice multi-colonna. D'altra parte, è possibile utilizzare al massimo uno dell'indice a colonna singola (dovrebbe cercare tutti i record con Column1 = 1, quindi controllare Column2 e Column3 in ognuno di questi).


24
Questo è corretto. Tuttavia, avere queste colonne come un singolo indice ognuna accelererebbe notevolmente le cose. Di solito uno dei valori nelle colonne ridurrà il set risultante così tanto che non importa cercare il resto senza un indice e l'ottimizzatore è bravo a scegliere questo valore.
TToni,

16

Un elemento che sembra essersi perso sono le trasformazioni a stella. Gli operatori di intersezione indice risolvono il predicato calcolando l'insieme di righe colpite da ciascuno dei predicati prima che venga eseguito qualsiasi I / O sulla tabella dei fatti. Su uno schema a stella indicizzeresti ogni singola chiave di dimensione e Query Optimizer può risolvere quali righe selezionare mediante il calcolo dell'intersezione dell'indice. Gli indici su singole colonne offrono la migliore flessibilità per questo.


+1 per la buona spiegazione collegata di come vengono utilizzati gli indici (ordinari), pertinenti alla domanda.
RobM

7

Se hai domande che utilizzeranno frequentemente un set di colonne relativamente statico, la creazione di un singolo indice di copertura che le include tutte migliorerà notevolmente le prestazioni.

Inserendo più colonne nel tuo indice, l'ottimizzatore dovrà accedere direttamente alla tabella solo se una colonna non è nell'indice. Li uso molto nel data warehousing. Il rovescio della medaglia è che fare questo può costare un sacco di spese generali, specialmente se i dati sono molto volatili.

La creazione di indici su singole colonne è utile per le operazioni di ricerca che si trovano frequentemente nei sistemi OLTP.

Dovresti chiederti perché stai indicizzando le colonne e come verranno utilizzate. Esegui alcuni piani di query e verifica quando vi si accede. L'ottimizzazione dell'indice è tanto istinto quanto la scienza.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.