Per le query che riguardano piccole porzioni delle righe della tabella, gli indici sono sempre utili, ci sono 100
righe o 1,000,000
.
Vai a questa voce nel mio blog per gli esempi con i piani e particolari prestazioni:
Le query come questo:
SELECT *
FROM table1 t1
JOIN table2 t2
ON t2.col = t1.col
sarà molto probabilmente l'uso HASH JOIN
. Verrà creata una tabella hash per la tabella più piccola e verranno utilizzate le righe della tabella più grande per sondare la tabella hash.
Per fare ciò, non è necessario alcun indice.
Tuttavia, questa ricerca:
SELECT *
FROM table1 t1
JOIN table2 t2
ON t2.col = t1.col
WHERE t1.othercol = @value
userà NESTED LOOPS
: le righe della tabella esterna (table1
) viene ricercato utilizzando un indice sulla table1.othercol
, e le righe della tabella interna (table2
) sarà cercato usando un indice su table2.col
.
Se non si dispone di un indice su col1
, verrà utilizzato un HASH JOIN
che richiede la scansione di tutte le righe da entrambe le tabelle e altre risorse per creare una tabella hash.
indici sono utili anche per le query di questo tipo:
SELECT t2.col
FROM table1 t1
JOIN table2 t2
ON t2.col = t1.col
, nel qual caso il motore non ha bisogno di leggere table2
sé a tutti: apparteneva il necessario per questa query può essere trovata nell'indice , che può essere molto più piccolo del tavolo stesso e più efficiente da leggere.
E, naturalmente, se avete bisogno dei vostri dati ordinati e hanno indici su entrambi table1.col
e table2.col
, quindi la seguente query:
SELECT *
FROM table1 t1
JOIN table2 t2
ON t2.col = t1.col
ORDER BY
t2.col
probabilmente utilizzare MERGE JOIN
metodo, che è super veloce se entrambi set di righe di input sono ordinati, e il suo output è anche ordinato, il che significa che ORDER BY
è gratuito.
Si noti che anche se non si dispone di un indice, un ottimizzatore può scegliere la tabella piccola Eager Spool
, che significa creare un indice temporaneo per la durata della query e rilasciare l'indice al termine della query.
Se la query è piccola, sarà molto veloce, ma, di nuovo, un indice non farà male (per le query SELECT
intendo). Se l'ottimizzatore non ne ha bisogno, non sarà usato.
Nota, tuttavia, che la creazione di un indice può influire sulle prestazioni di DML
, ma è un'altra storia.
In realtà, il database non ordina le chiavi all'interno di una singola pagina. Quindi, fino a quando non andrà oltre questo punto, non ci sarà alcun beneficio. E probabilmente per diverse pagine oltre. – dkretz
@Robert: hanno anche un vantaggio quando si utilizzano solo le colonne indicizzate nella query o quando è necessario ordinare i dati. E no, non sono sempre un vantaggio sulla clausola WHERE, solo su quelli molto selettivi. – Quassnoi
Quassnoi, ho visto il tuo post sul blog. Solo per quello che sai, la decisione finale sull'indicizzazione del nostro database (basata su informazioni aggiuntive a questo post: stackoverflow.com/questions/1033796/...) era di indicizzare tutte le chiavi esterne ECCETTO quelle che partecipano ai join alle tabelle di ricerca contenenti MENO DI 10 Records. –