Cas A
Requête:
WHERE thread_id = 12345
AND placeholder = FALSE
ORDER BY some_column DESC
LIMIT 20
Indice:
(thread_id, date_created)
Plan:
Index is used
Using Where
Using filesort
Pas de problème là-bas, non? Si l'index est utilisé (pour correspondre partiellement à la WHERE
condition), nous avons encore besoin d'une opération de tri pour classer les résultats par some_column
(qui n'est pas dans l'index). Nous avons également besoin d'une vérification supplémentaire (Utilisation de Où) pour ne conserver que les lignes qui correspondent à la 2ème condition. D'ACCORD.
Cas B (la question)
Requête:
WHERE thread_id = 12345
AND placeholder = FALSE
ORDER BY date_created DESC
LIMIT 20
Indice:
(thread_id, date_created)
Plan:
Index is used
Using Where
-- no "Using filesort"
Alors, pourquoi n'a-t-il pas besoin d'un tri ici ? Parce que l'index est suffisant pour trier comme la requête le souhaite. Il y a bien sûr le problème supplémentaire de la condition supplémentaire ( AND placeholder = FALSE
) qui n'est pas couverte par l'index.
OK mais nous n'avons pas vraiment besoin d'un tri ici. L'index peut nous fournir des résultats qui correspondent à la première condition ( WHERE thread_id = 12345
) et sont dans l'ordre souhaité pour la sortie. La seule vérification supplémentaire dont nous avons besoin - et ce que fait le plan - est d'obtenir les lignes de la table, dans l'ordre fourni par l'index, et de vérifier cette 2ème condition jusqu'à ce que nous obtenions 20 correspondances. C'est ce que signifie ** Utiliser où "".
Nous pouvons obtenir les 20 matchs dans les 20 premières lignes (donc vraiment bons et rapides) ou dans les 100 premiers (toujours probablement assez rapides) ou dans les premiers 1000000 (probablement très, très lents) ou nous pouvons obtenir seulement 19 matches de la même après avoir lu toutes les lignes correspondantes de l'index (vraiment très lent sur une grande table). Tout dépend de la distribution des données.
Cas C (plan encore meilleur)
Requête:
WHERE thread_id = 12345
AND placeholder = FALSE
ORDER BY date_created DESC
LIMIT 20
Indice:
(placeholder, thread_id, date_created)
Plan:
Index is used
-- no "Using Where"
-- no "Using filesort"
Maintenant, notre index correspond à la fois aux conditions et à la commande par. Le plan est assez simple: obtenez les * 20 premières correspondances de l'index et lisez les lignes correspondantes du tableau. Aucune vérification supplémentaire (pas d '"utilisation où") et aucun tri (pas d' "utilisation de tri de fichiers") nécessaires.
first *: les 20 premiers lors de la lecture de l'index vers l'arrière depuis la fin (comme nous l'avons fait ORDER BY .. DESC
) mais ce n'est pas un problème. Les index B-tree peuvent être lus en avant et en arrière avec des performances presque égales.