Fall A
Abfrage:
WHERE thread_id = 12345
AND placeholder = FALSE
ORDER BY some_column DESC
LIMIT 20
Index:
(thread_id, date_created)
Planen:
Index is used
Using Where
Using filesort
Kein Problem, oder? Wenn der Index verwendet wird (um teilweise mit der WHERE
Bedingung übereinzustimmen), benötigen wir noch eine Sortieroperation, um die Ergebnisse nach zu sortieren some_column
(was nicht im Index enthalten ist). Wir benötigen außerdem eine zusätzliche Prüfung (Verwenden von Where), um nur die Zeilen beizubehalten, die auch der zweiten Bedingung entsprechen. OK.
Fall B (die Frage)
Abfrage:
WHERE thread_id = 12345
AND placeholder = FALSE
ORDER BY date_created DESC
LIMIT 20
Index:
(thread_id, date_created)
Planen:
Index is used
Using Where
-- no "Using filesort"
Also, warum braucht es nicht eine Art hier ? Weil der Index ausreicht, um nach Abfrage zu sortieren. Es gibt natürlich das zusätzliche Problem der zusätzlichen Bedingung ( AND placeholder = FALSE
), die nicht vom Index abgedeckt wird.
OK, aber wir brauchen hier nicht wirklich eine Sorte. Der Index kann uns Ergebnisse liefern, die der ersten Bedingung ( WHERE thread_id = 12345
) entsprechen und in der gewünschten Reihenfolge für die Ausgabe vorliegen . Die einzige zusätzliche Überprüfung, die wir benötigen - und was der Plan tut - besteht darin, die Zeilen aus der Tabelle in der vom Index angegebenen Reihenfolge abzurufen und diese zweite Bedingung zu überprüfen, bis wir 20 Übereinstimmungen erhalten. Das ist es, was ** Using Where "" bedeutet.
Wir können die 20 Übereinstimmungen in den ersten 20 Reihen (also wirklich gut und schnell) oder in den ersten 100 (wahrscheinlich immer noch schnell genug) oder in den ersten 1000000 (wahrscheinlich sehr, sehr langsam) bekommen, oder wir können nur 19 Übereinstimmungen von der bekommen Tabelle auch nach dem Lesen aller übereinstimmenden Zeilen aus dem Index (wirklich sehr langsam auf einer großen Tabelle). Alles hängt von der Verteilung der Daten ab.
Fall C (noch besserer Plan)
Abfrage:
WHERE thread_id = 12345
AND placeholder = FALSE
ORDER BY date_created DESC
LIMIT 20
Index:
(placeholder, thread_id, date_created)
Planen:
Index is used
-- no "Using Where"
-- no "Using filesort"
Jetzt entspricht unser Index sowohl den Bedingungen als auch der Reihenfolge von. Der Plan ist ziemlich einfach: Holen Sie sich die ersten * 20 Übereinstimmungen aus dem Index und lesen Sie die entsprechenden Zeilen aus der Tabelle. Keine zusätzliche Prüfung (kein "Using Where") und keine Sortierung (kein "Using filesort") erforderlich.
first *: die ersten 20, wenn der Index vom Ende rückwärts gelesen wird (wie wir es getan haben ORDER BY .. DESC
), aber das ist kein Problem. B-Tree-Indizes können mit nahezu gleicher Leistung vorwärts und rückwärts gelesen werden.