Uno o due indici?


11

Ho il seguente indice creato su una tabella nel mio database:

CREATE INDEX [idx_index1]
on [table1]
(col1, col2, col3)

Il server suggerisce il seguente indice "mancante":

CREATE INDEX [idx_index2]
on [table1]
(col1, col2)
INCLUDE (col3, col4, col5, col6....)

Mi sembra logico modificare la definizione dell'indice esistente per includere le colonne suggerite, piuttosto che creare un nuovo indice che deve essere mantenuto. Una query che seleziona su col1 e col2 potrebbe utilizzare index1 con la stessa efficacia di index2. Ho ragione o forse mi sto perdendo qualcosa?

Risposte:


12

E così entra nell'arte del tuning delle performance e delle strategie di indicizzazione ...

Mi sembra logico modificare la definizione dell'indice esistente per includere le colonne suggerite

Prenderò il tuo preventivo e scriverò una terza definizione di indice:

create index [idx_index3]
on [table1] (col1, col2, col3)
include (col4, col5, col6....);

Questa dovrebbe essere la CREATE INDEXdichiarazione che corrisponde alla tua dichiarazione citata.

Potrebbe benissimo essere una soluzione prudente, ma dipende . Ecco un paio di esempi quando dico che dipende.

Se hai un carico di lavoro comune che consiste principalmente di query come questa:

select col1, col2, col3
from table1
where col1 = 1
and col2 = 2
and col3 = 3;

Quindi il tuo idx_index1indice sarebbe solido. Perfettamente stretto, è un indice che soddisfa quella query senza dati estranei al suo interno (non tenendo conto della definizione dell'indice cluster, se del caso).

Ma se hai un carico di lavoro che consiste in query principalmente come le seguenti:

select co11, col2, col3, col4, col5
from table1
where col1 = 1
and col2 = 2;

Quindi idx_index2sarebbe saggio, in quanto è quello che viene chiamato un indice di copertura che impedisce la necessità di una chiave di ricerca all'indice cluster (o di una ricerca RID all'heap). Tale definizione di indice non cluster includerebbe esclusivamente tutti i dati richiesti dalla query.

Con la tua raccomandazione, sarebbe adatto per una query come la seguente:

select co11, col2, col3, col4, col5
from table1
where col1 = 1
and col2 = 2
and col3 = 3;

La tua idx_index3raccomandazione sarebbe un indice di copertura che soddisfi i criteri di ricerca per la query sopra.

Il punto su cui sto cercando di arrivare è in una domanda isolata come questa a cui non possiamo rispondere in modo definitivo. Tutto dipende da quale sia il carico di lavoro comune e frequente. Ovviamente puoi sempre definire tutti e tre questi indici per gestire ogni tipo di query di esempio, ma poi viene messo in discussione la manutenzione che sarà richiesta per mantenere aggiornati questi indici (pensa: INSERTI, AGGIORNAMENTI, ELIMINA). Questo è il sovraccarico degli indici.

È necessario analizzare e valutare il carico di lavoro e determinare dove saranno i vantaggi migliori. Se la prima query di esempio è la più comune di gran lunga eseguita dozzine di volte al secondo e c'è una query molto rara come la terza query di esempio, non avrebbe senso gonfiare le pagine a livello di foglia dell'indice con il INCLUDEcolonne non chiave. Tutto dipende dal carico di lavoro.

Se capisci le strategie di indicizzazione prudente e comprendi il tuo carico di lavoro comune, applicando entrambi, sarai in grado di trovare qual è la strada migliore da prendere.


Dovrò digerirlo per un po ', ma sembra una buona risposta. Suppongo che sia stato un refuso che l '"indice3" che hai definito abbia col3 come una colonna di uguaglianza E una colonna inclusa?
paul

Sì :-) Buona cattura. L'ho modificato.
Thomas Stringer,

Per non parlare del fatto che se la tabella ha solo i numeri 1-6, è piuttosto sciocco indicizzare 1 e 2 e includere 3-5.
Kenneth Fisher,

1
@KennethFisher - perché sarebbe sciocco? Sembra una cosa abbastanza ragionevole da fare se la struttura del database e il carico di lavoro lo giustificano. Ad esempio, se si dispone di una query che seleziona le colonne 1-5 in base ai valori delle colonne 1 e 2, e forse la colonna 6 è una colonna nvarchar (max) con cui non si desidera gonfiare l'indice.
paul

1
@paulH Probabilmente è solo la mia opinione, ma nel momento in cui hai aggiunto abbastanza colonne all'inclusione che il tuo indice ha il 90 +% delle tue colonne nella tabella, hai gonfiato il tuo indice al punto che la lettura extra per andare alla tabella di per sé non è poi così importante. Ora ci sono certamente delle eccezioni .. se cols 1-5 sono tutti int e col6 è un varchar (max), allora potrei farlo. Ma in generale li guarderei MOLTO attentamente.
Kenneth Fisher,

7

Hai effettivamente ragione e hai scoperto perché è importante che un DBA riveda sempre i "suggerimenti" proposti dai DMV dell'indice mancanti ecc.

Si consideri che i suggerimenti offerti dai DMV di indice mancanti sono proposti in modo isolato, il che significa che SQL Server ha deciso che un indice della struttura consigliata sarebbe vantaggioso per la query, indipendentemente da quali altre strutture di indice potrebbero già esistere.


3

Un po 'di più, su una delle implicazioni della risposta di Thomas:

Egli ha detto:

Ovviamente puoi sempre definire tutti e tre questi indici per gestire ogni tipo di query di esempio, ma poi viene messo in discussione la manutenzione che sarà richiesta per mantenere aggiornati questi indici (pensa: INSERTI, AGGIORNAMENTI, ELIMINA). Questo è il sovraccarico degli indici.

Quindi, un'altra grande domanda diventa: con che frequenza viene aggiornata la tabella?

Considera innanzitutto un esempio di una tabella che viene costantemente aggiornata, come ad esempio una ORDERStabella di vendita al dettaglio che riflette l'attività dei consumatori del sito Web ... lì, vuoi essere coscienzioso sull'avere più indici, perché aumentano il lavoro svolto da aggiornamenti costanti, e quindi incide costantemente sulle prestazioni del database.

D'altra parte, si consideri una tabella che viene aggiornato solo come parte di installazione sito web - il tavolo in fase di aggiornamento UNA VOLTA per la maggior parte dei valori, ei valori di rado ha aggiunto - c'è, rallentamenti di aggiornamento sono praticamente non una considerazione. Più indici potrebbero rallentare ricostruzioni e rimbalzi degli indici del database, ma purché siano abbastanza veloci, SENTIRE GRATUITAMENTE: se più indici accelerano le letture, procedi.

Un caso intermedio potrebbe essere una tabella che viene normalmente aggiornata solo in un processo batch durante la notte. Lì, i rallentamenti dell'aggiornamento da più indici non influirebbero sulle prestazioni diurne - influenzerebbero solo (1) il tempo impiegato, per eseguire quella manutenzione batch notturna, (2) le prestazioni di tutti i processi simultanei e (3) il tempo impiegato per attività di manutenzione del database come la riorganizzazione dell'indice. Quindi, fintanto che i processi in quelle 3 arene funzioneranno abbastanza velocemente per te ... crea gli indici che accelerano le query.

HTH ...

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.