@Pierre 303 l'ha già detto, ma lo dirò di nuovo. DO utilizza indici su combinazioni di colonne. Un indice combinato su (a, b)
è solo leggermente più lento per le query su a
rispetto a un indice su a
da solo ed è decisamente migliore se la query combina entrambe le colonne. Alcuni database possono unire indici su a
e b
prima di colpire la tabella, ma questo non è quasi buono come avere un indice combinato. Quando crei un indice combinato, devi inserire la colonna che è più probabile che venga ricercata per prima nell'indice combinato.
Se il tuo database lo supporta, DO metti indici su funzioni che appaiono nelle query piuttosto che nelle colonne. (Se stai chiamando una funzione su una colonna, gli indici su quella colonna sono inutili.)
Se utilizzi un database con tabelle temporanee reali che puoi creare e distruggere al volo (ad esempio PostgreSQL, MySQL, ma non Oracle), quindi DO creare indici su tabelle temporanee.
Se utilizzi un database che lo consente (ad es. Oracle), DO blocca in piani di query validi. 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 si noteranno miglioramenti del piano: la query non è un collo di bottiglia. Ma un singolo piano errato può distruggere un sito occupato.
NON hai indici sulle tabelle su cui stai per caricare un grosso carico di dati. È molto, molto più veloce rilasciare gli indici, caricare i dati, quindi ricostruire gli indici anziché conservarli mentre carichi la tabella.
NON utilizza gli indici sulle query che devono accedere a più di una piccola frazione di una tabella di grandi dimensioni. (Quanto piccolo dipende dall'hardware: il 5% è una regola empirica.) Ad esempio, se si dispone di dati con nomi e sesso, 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é sarà comunque necessario accedere al 50% delle righe. Invece, vuoi veramente usare 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 cercare il disco. Le ricerche sul disco sono lente. Per esempio, di recente sono riuscito a velocizzare una query lunga un'ora simile a:
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
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 creato. Un indice dà una rapida occhiata per dire dove sono i dati nella tabella. Di solito è una vittoria visto che guarderai solo i dati che devi guardare. Ma non sempre, soprattutto se alla fine si guardano molti dati. I dischi trasmettono bene i dati, ma rallentano le ricerche. La ricerca casuale dei dati sul disco richiede 1/200 di secondo. La versione lenta della query finì per fare qualcosa come 600.000 di quelle e ci volle quasi un'ora. (Ha fatto più ricerche, ma la cache ne ha catturate alcune.) Al contrario la versione veloce sapeva che doveva leggere tutto e trasmettere dati a qualcosa come 70 MB / secondo. Ha ottenuto una tabella da 11 GB in meno di 3 minuti.