Gemäß Kapitel 9 (Parser und Optimierer), Seite 172 des Buches Grundlegendes zu MySQL-Interna von Sasha Pachev
Hier ist die Aufteilung der Auswertung einer Abfrage nach folgenden Aufgaben:
- Bestimmen Sie, mit welchen Schlüsseln die Datensätze aus Tabellen abgerufen werden können, und wählen Sie für jede Tabelle den besten aus.
- Entscheiden Sie für jede Tabelle, ob ein Tabellenscan besser ist als das Lesen auf einem Schlüssel. Wenn viele Datensätze mit dem Schlüsselwert übereinstimmen, werden die Vorteile des Schlüssels verringert und der Tabellenscan wird schneller.
- Bestimmen Sie die Reihenfolge, in der Tabellen verknüpft werden sollen, wenn mehr als eine Tabelle in der Abfrage vorhanden ist.
- Schreiben Sie die WHERE-Klauseln neu, um toten Code zu beseitigen, die unnötigen Berechnungen zu reduzieren und die Einschränkungen nach Möglichkeit zu ändern, um die Verwendung von Schlüsseln zu ermöglichen.
- Beseitigen Sie nicht verwendete Tabellen aus dem Join.
- Bestimmen Sie, ob Schlüssel für
ORDER BY
und verwendet werden können GROUP BY
.
- Versuchen Sie, Unterabfragen zu vereinfachen und festzustellen, inwieweit ihre Ergebnisse zwischengespeichert werden können.
- Ansichten zusammenführen (Ansichtsreferenz als Makro erweitern)
Auf derselben Seite steht:
In der Terminologie des MySQL-Optimierers besteht jede Abfrage aus einer Reihe von Joins. Der Begriff Join wird hier breiter verwendet als in SQL-Befehlen. Eine Abfrage für nur eine Tabelle ist eine entartete Verknüpfung. Während wir normalerweise nicht daran denken, Datensätze aus einer Tabelle als Join zu lesen, funktionieren dieselben Strukturen und Algorithmen wie bei herkömmlichen Joins perfekt, um die Abfrage mit nur einer Tabelle aufzulösen.
EPILOG
Aufgrund der vorhandenen Schlüssel, der Datenmenge und des Ausdrucks der Abfrage können MySQL-Verknüpfungen manchmal zu unserem eigenen Wohl (oder um zu uns zurückzukehren) beitragen und Ergebnisse erzielen, die wir nicht erwartet haben und die wir nicht schnell erklären können.
Ich habe schon früher über diese Kuriosität geschrieben
weil der MySQL Query Optimizer bestimmte Schlüssel während der Auswertung der Abfrage verwerfen könnte.
@ Phils Kommentar hilf mir, diese Antwort zu posten (+1 für @ Phils Kommentar)
@ ypercubes Kommentar (+1 auch für diesen) ist eine kompakte Version meines Posts, da MySQLs Query Optimizer primitiv ist. Leider muss es sein, da es sich um externe Speicher-Engines handelt.
FAZIT
Was Ihre eigentliche Frage betrifft, würde das MySQL-Abfrageoptimierungsprogramm die Leistungsmetriken jeder Abfrage ermitteln, wenn diese erledigt ist
- Reihen zählen
- Schlüssel auswählen
- Massieren von intermittierenden Ergebnissätzen
- Oh ja, mache den eigentlichen JOIN
Wahrscheinlich müssten Sie die Ausführungsreihenfolge erzwingen, indem Sie die Abfrage neu schreiben (refactoring)
Hier ist die erste Abfrage, die Sie gegeben haben
select count(*)
from table1 a
join table2 b
on b.key_col=a.key_col
where b.tag = 'Y';
Versuchen Sie es neu zu schreiben, um zuerst das WHERE auszuwerten
select count(*)
from table1 a
join (select key_col from table2 where tag='Y') b
on b.key_col=a.key_col;
Das würde definitiv den EXPLAIN-Plan ändern. Es könnte zu besseren oder schlechteren Ergebnissen führen.
Ich habe einmal eine Frage in StackOverflow beantwortet, in der ich diese Technik angewendet habe. Das EXPLAIN war horrend, aber die Aufführung war Dynamit. Es funktionierte nur, weil die richtigen Indizes vorhanden waren und LIMIT in einer Unterabfrage verwendet wurde .
Ähnlich wie bei den Aktienkursen gelten bei Abfragen und dem Versuch, sie auszudrücken, Beschränkungen, die Ergebnisse können variieren und die Wertentwicklung in der Vergangenheit ist kein Hinweis auf zukünftige Ergebnisse.