@Pierre 303 lo ha già detto, ma lo dirò di nuovo. DO utilizzare indici su combinazioni di colonne. Un indice combinato attivato (a, b)
è solo leggermente più lento per le query a
rispetto a un indice a
solo ed è notevolmente migliore se la query combina entrambe le colonne. Alcuni database possono unire gli indici sopra a
e b
prima di colpire la tabella, ma questo non è quasi come avere un indice combinato. Quando si crea un indice combinato, è necessario inserire prima la colonna che è più probabile che venga cercata nell'indice combinato.
Se il database lo supporta, NON inserire indici nelle funzioni visualizzate nelle query anziché nelle colonne. (Se stai chiamando una funzione su una colonna, gli indici su quella colonna sono inutili.)
Se si utilizza un database con i veri tabelle temporanee che è possibile creare e distruggere al volo (ad esempio, PostgreSQL, MySQL, ma non Oracle), quindi NON creare indici su tabelle temporanee.
Se si utilizza un database che lo consente (ad es. Oracle), bloccare DO in buoni piani di query. Gli ottimizzatori di query nel tempo modificheranno i piani di query. Di solito migliorano il piano. Ma a volte lo fanno drammaticamente peggio. In genere non noterai davvero miglioramenti del piano: la query non era un collo di bottiglia. Ma un singolo piano negativo può abbattere un sito occupato.
NON avere indici sulle tabelle su cui stai per caricare un grande volume di dati. È molto, molto più veloce eliminare gli indici, caricare i dati, quindi ricostruire gli indici piuttosto che mantenerli mentre si carica la tabella.
NON utilizzare gli indici per le query che devono accedere a più di una piccola parte di una tabella di grandi dimensioni. (Quanto piccolo dipende dall'hardware. Il 5% è una regola empirica decente.) Ad esempio, se si hanno dati con nomi e genere, i nomi sono un buon candidato per l'indicizzazione poiché ogni nome dato rappresenta una piccola frazione delle righe totali. Non sarebbe utile indicizzare il genere poiché dovrai comunque accedere al 50% delle righe. Invece, vuoi davvero utilizzare una scansione completa della tabella. Il motivo è che gli indici finiscono per accedere a un file di grandi dimensioni in modo casuale, causando la necessità di ricerche su disco. Le ricerche su disco sono lente. Ad esempio, recentemente sono riuscito a velocizzare un'interrogazione di un'ora che sembrava:
SELECT small_table.id, SUM(big_table.some_value)
FROM small_table
JOIN big_table
ON big_table.small_table_id = small_table.id
GROUP BY small_table.id
a meno di 3 minuti riscrivendolo come segue:
SELECT small_table.id, big_table_summary.summed_value
FROM small_table
JOIN (
SELECT small_table_id, SUM(some_value) as summed_value
FROM big_table
GROUP BY small_table_id
) big_table_summary
ON big_table_summary.small_table_id = small_table.id
che ha costretto il database a capire che non dovrebbe tentare di utilizzare l'indice allettante su big_table.small_table_id
. (Un buon database, come Oracle, dovrebbe capirlo da solo. Questa query era in esecuzione su MySQL.)
Aggiornamento: ecco una spiegazione del punto di ricerca del disco che ho fatto. Un indice fornisce una rapida occhiata per dire dove sono i dati nella tabella. Di solito si tratta di una vittoria, dato che guarderai solo i dati che devi guardare. Ma non sempre, in particolare se alla fine esaminerai molti dati. I dischi trasmettono bene i dati, ma rallentano le ricerche. Una ricerca casuale di dati su disco richiede 1/200 di secondo. La versione lenta della query finì per fare qualcosa come 600.000 di quelli e impiegò quasi un'ora. (Ha fatto più ricerche di così, ma la cache ha catturato alcune di quelle.) Al contrario, la versione veloce sapeva che doveva leggere tutto e trasmettere i dati in streaming a qualcosa come 70 MB / secondo. Ha superato un tavolo da 11 GB in meno di 3 minuti.