Die Entwicklung erfolgt kontinuierlich, d. h., Optimierungstipps sind niemals auf Dauer gültig. Die folgende Liste zeigt einige interessante Tricks, mit denen Sie ein wenig herumprobieren können:
Verwendung von Klauseln in Unterabfragen, die die Anzahl oder Reihenfolge der Datensätze in der Unterabfrage betreffen. Zum Beispiel:
SELECT * FROM t1 WHERE t1.column1 IN (SELECT column1 FROM t2 ORDER BY column1); SELECT * FROM t1 WHERE t1.column1 IN (SELECT DISTINCT column1 FROM t2); SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t2 LIMIT 1);
Ersetzen Sie einen Join durch eine Unterabfrage. Probieren Sie z. B. Folgendes aus.
SELECT DISTINCT column1 FROM t1 WHERE t1.column1 IN ( SELECT column1 FROM t2);
So hätte dies ursprünglich ausgesehen:
SELECT DISTINCT t1.column1 FROM t1, t2 WHERE t1.column1 = t2.column1;
Einige Unterabfragen können aus Gründen der Kompatibilität mit älteren MySQL-Versionen, die Unterabfragen nicht unterstützen, in Joins umgewandelt werden. Allerdings wird hierdurch in einigen Fällen die Leistungsfähigkeit beeinträchtigt. Siehe auch Abschnitt 13.2.8.11, „Umschreiben von Unterabfragen in Joins für frühere MySQL-Versionen“.
Verschieben Sie Klauseln von außen in die Unterabfrage. Verwenden Sie beispielsweise diese Abfrage …
SELECT * FROM t1 WHERE s1 IN (SELECT s1 FROM t1 UNION ALL SELECT s1 FROM t2);
… statt dieser:
SELECT * FROM t1 WHERE s1 IN (SELECT s1 FROM t1) OR s1 IN (SELECT s1 FROM t2);
Ein weiteres Beispiel: Verwenden Sie diese Abfrage …
SELECT (SELECT column1 + 5 FROM t1) FROM t2;
… statt dieser:
SELECT (SELECT column1 FROM t1) + 5 FROM t2;
Verwenden Sie eine Datensatzunterabfrage statt einer korrelierten Unterabfrage. Verwenden Sie beispielsweise diese Abfrage …
SELECT * FROM t1 WHERE (column1,column2) IN (SELECT column1,column2 FROM t2);
… statt dieser:
SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t2 WHERE t2.column1=t1.column1 AND t2.column2=t1.column2);
Verwenden Sie NOT (a = ANY (...))
statt
a <> ALL (...)
.
Verwenden Sie x = ANY (
statt
table
containing (1,2)
)x=1 OR x=2
.
Verwenden Sie = ANY
statt
EXISTS
.
Bei unkorrelierten Unterabfragen, die immer genau einen
Datensatz zurückgeben, ist IN
immer
langsamer als =
. Verwenden Sie
beispielsweise diese Abfrage …
SELECT * FROM t1 WHERE t1.col_name
= (SELECT a FROM t2 WHERE b =some_const
);
… statt dieser:
SELECT * FROM t1 WHERE t1.col_name
IN (SELECT a FROM t2 WHERE b =some_const
);
Aufgrund dieser Tricks können Programme schneller, aber auch
langsamer werden. Mithilfe von MySQL-Funktionen wie
BENCHMARK()
können Sie überprüfen, was
in Ihrer speziellen Situation hilfreich sein kann. Siehe auch
Abschnitt 12.10.3, „Informationsfunktionen“.
Die folgenden Optimierungen nimmt MySQL selbst vor:
MySQL führt nichtkorrelierte Unterabfragen nur einmal
aus. Mit EXPLAIN
können Sie
sicherstellen, dass eine gegebene Unterabfrage wirklich
nichtkorreliert ist.
MySQL schreibt IN
-,
ALL
-, ANY
- und
SOME
-Unterabfragen neu, um möglichst
davon zu profitieren, dass die Auswahllistenspalten in der
Unterabfrage indiziert sind.
MySQL ersetzt Unterabfragen der folgenden Form durch eine
Indexsuchfunktion, die EXPLAIN
als
speziellen Join-Typ beschreibt
(unique_subquery
oder
index_subquery
):
... IN (SELECTindexed_column
FROMsingle_table
...)
MySQL erweitert Ausdrücke der folgenden Form mit einem
Ausdruck mit MIN()
oder
MAX()
, sofern
NULL
-Werte oder Leermengen vorhanden
sind:
value
{ALL|ANY|SOME} {> | < | >= | <=} (non-correlated subquery
)
Betrachten Sie etwa folgende
WHERE
-Klausel:
WHERE 5 > ALL (SELECT x FROM t)
Diese könnte vom Optimierer wie folgt geändert werden:
WHERE 5 > (SELECT MAX(x) FROM t)
Es gibt ein Kapitel „How MySQL Transforms Subqueries“ („Wie MySQL Unterabfragen transformiert“) im Handbuch „MySQL Internals“ (MySQL-Interna, derzeit nur auf Englisch verfügbar), welches Sie unter http://dev.mysql.com/doc/ erhalten.
Dies ist eine Übersetzung des MySQL-Referenzhandbuchs, das sich auf dev.mysql.com befindet. Das ursprüngliche Referenzhandbuch ist auf Englisch, und diese Übersetzung ist nicht notwendigerweise so aktuell wie die englische Ausgabe. Das vorliegende deutschsprachige Handbuch behandelt MySQL bis zur Version 5.1.