Caso A
Query:
WHERE thread_id = 12345
AND placeholder = FALSE
ORDER BY some_column DESC
LIMIT 20
Indice:
(thread_id, date_created)
Piano:
Index is used
Using Where
Using filesort
Nessun problema, vero? Se viene utilizzato l'indice (per abbinare parzialmente la WHERE
condizione), abbiamo ancora bisogno di un'operazione di ordinamento per ordinare i risultati per some_column
(che non è nell'indice). È inoltre necessario un controllo aggiuntivo (Utilizzo di Where) per mantenere anche solo le righe che corrispondono alla seconda condizione. OK.
Caso B (la domanda)
Query:
WHERE thread_id = 12345
AND placeholder = FALSE
ORDER BY date_created DESC
LIMIT 20
Indice:
(thread_id, date_created)
Piano:
Index is used
Using Where
-- no "Using filesort"
Quindi, perché non ha bisogno di una sorta qui ? Perché l'indice è sufficiente per ordinare come vuole la query. Esiste ovviamente il problema aggiuntivo della condizione aggiuntiva ( AND placeholder = FALSE
) che non è coperta dall'indice.
OK ma non abbiamo davvero bisogno di una specie qui. L'indice può fornirci risultati che corrispondono alla prima condizione ( WHERE thread_id = 12345
) e sono nell'ordine desiderato per l'output. L'unico controllo aggiuntivo di cui abbiamo bisogno - e ciò che fa il piano - è quello di ottenere le righe dalla tabella, nell'ordine fornito dall'indice, e controllare questa seconda condizione fino a quando non otteniamo 20 corrispondenze. Questo è ciò che significa "Using Where" ".
Potremmo ottenere le 20 partite nelle prime 20 righe (quindi davvero buone e veloci) o nelle prime 100 (ancora probabilmente abbastanza veloci) o nelle prime 1000000 (probabilmente molto, molto lente) o potremmo ottenere solo 19 partite dal tabella anche dopo aver letto tutte le righe corrispondenti dall'indice (davvero molto lento su una grande tabella). Tutto dipende dalla distribuzione dei dati.
Caso C (piano ancora migliore)
Query:
WHERE thread_id = 12345
AND placeholder = FALSE
ORDER BY date_created DESC
LIMIT 20
Indice:
(placeholder, thread_id, date_created)
Piano:
Index is used
-- no "Using Where"
-- no "Using filesort"
Ora il nostro indice corrisponde a entrambe le condizioni e l'ordine per. Il piano è piuttosto semplice: ottieni le prime * 20 corrispondenze dall'indice e leggi le righe corrispondenti dalla tabella. Nessun controllo extra (nessun "utilizzo di Where") e nessun ordinamento (nessun "utilizzo di filesort") necessario.
primo *: i primi 20 quando si legge l'indice all'indietro dalla fine (come abbiamo fatto ORDER BY .. DESC
) ma non è un problema. Gli indici B-tree possono essere letti in avanti e indietro con prestazioni quasi uguali.