:: DEVELOPER ZONE
Die WHERE-Optimierungen wurden hier in den SELECT-Teil
aufgenommen, weil sie meist in Verbindung mit SELECT benutzt werden,
aber dieselben Optimierungen treffen für WHERE bei DELETE-
und UPDATE-Statements zu.
Beachten Sie auch, dass dieser Abschnitt nicht vollständig ist. MySQL führt viele Optimierungen durch und wir hatten noch keine Zeit, alle davon zu dokumentieren.
Einige der Optimierungen, die MySQL durchführt, sind unten aufgeführt:
Entfernung unnötiger Klammern:
((a AND b) AND c OR (((a AND b) AND (c AND d)))) -> (a AND b AND c) OR (a AND b AND c AND d)
Konstanten-'Falten' (Folding):
(a<b AND b=c) AND a=5 -> b>5 AND b=c AND a=5
Bedingungsentfernung bei Konstanten (notwendig wegen Konstanten-'Falten'):
(B>=5 AND B=5) OR (B=6 AND 5=5) OR (B=7 AND 5=6) -> B=5 OR B=6
Konstante Ausdrücke, die von Indexen benutzt werden, werden nur einmal ausgewertet.
COUNT(*) auf eine einzelne Tabelle ohne ein WHERE wird direkt
aus der Tabelleninformation abgerufen. Das wird auch bei jeglichen
NOT NULL-Ausdrücken gemacht, wenn diese nur für eine Tabelle benutzt
werden.
Früherkennung ungültiger Konstanten-Ausdrücke. MySQL stellt schnell fest,
dass einige SELECT-Statements unmöglich sind, und gibt keine Zeilen
zurück.
HAVING wird mit WHERE vereinigt, wenn Sie GROUP BY
oder Gruppen-Funktionen (COUNT(), MIN() usw.) nicht
benutzen.
Für jeden Sub-Join wird ein einfacheres WHERE konstruiert, um eine
schnelle WHERE-Evaluierung für jeden Sub-Join zu erzielen, und auch,
um Datensätze so bald wie möglich überspringen zu können.
Alle Konstanten-Tabellen werden zuerst gelesen, vor jeder anderen Tabelle in der Anfrage. Eine Konstanten-Tabelle ist:
Eine leere Tabelle oder eine Tabelle mit 1 Zeile.
Eine Tabelle, die bei einer WHERE-Klausel auf einen
UNIQUE-Index oder einen PRIMARY KEY benutzt wird, wobei alle
Index-Teile mit konstanten Ausdrücken benutzt werden und die Index-Teile
als NOT NULL definiert sind.
Alle folgenden Tabellen werden als Konstanten-Tabellen benutzt:
mysql> SELECT * FROM t WHERE primary_key=1;
mysql> SELECT * FROM t1,t2
WHERE t1.primary_key=1 AND t2.primary_key=t1.id;
Die beste Join-Kombination, um Tabellen zu verknüpfen, wird gefunden, wenn
man alle Möglichkeiten probiert. Wenn alle Spalten in ORDER BY und
in GROUP BY aus derselben Tabelle stammen, wird diese Tabelle
vorzugsweise vorn hingestellt, wenn verknüpft wird.
Wenn es eine ORDER BY-Klausel und eine andere GROUP BY-Klausel gibt, oder wenn ORDER BY oder GROUP BY Spalten
aus Tabellen enthält, die nicht aus der ersten Tabelle in der Join-Reihe
stammen, wird eine temporäre Tabelle erzeugt.
Wenn Sie SQL_SMALL_RESULT benutzen, benutzt MySQL eine temporäre
Tabelle im Arbeitsspeicher.
Jeder Tabellen-Index wird abgefragt und der beste Index, der weniger als 30% der Zeilen überspannt, wird benutzt. Wenn ein solcher Index nicht gefunden werden kann, wird ein schneller Tabellenscan benutzt.
In einigen Fällen kann MySQL Zeilen vom Index lesen, ohne überhaupt in der Daten-Datei nachzuschlagen. Wenn alle Spalten, die vom Index benutzt werden, numerisch sind, wird nur der Index-Baum benutzt, um die Anfrage aufzulösen.
Bevor jeder Datensatz herausgegeben wird, werden die, die nicht mit der
HAVING-Klausel übereinstimmen, übersprungen.
Einige Beispiele von Anfragen, die sehr schnell sind:
mysql> SELECT COUNT(*) FROM tabelle;
mysql> SELECT MIN(schluessel_teil1),MAX(schluessel_teil1) FROM tabelle;
mysql> SELECT MAX(schluessel_teil2) FROM tabelle
WHERE schluessel_teil_1=konstante;
mysql> SELECT ... FROM tabelle
ORDER BY schluessel_teil1,schluessel_teil2,... LIMIT 10;
mysql> SELECT ... FROM tabelle
ORDER BY schluessel_teil1 DESC,schluessel_teil2 DESC,... LIMIT 10;
Die folgenden Anfragen werden aufgelöst, indem nur der Index-Baum benutzt wird (unter der Annahme, dass die indizierten Spalten numerisch sind):
mysql> SELECT schluessel_teil1,schluessel_teil2 FROM tabelle WHERE schluessel_teil1=val;
mysql> SELECT COUNT(*) FROM tabelle
WHERE schluessel_teil1=val1 AND schluessel_teil2=val2;
mysql> SELECT schluessel_teil2 FROM tabelle GROUP BY schluessel_teil1;
Die folgenden Anfragen benutzen Indexierung, um die Zeilen in sortierter Reihenfolge abzufragen, ohne einen separaten Sortierdurchgang:
mysql> SELECT ... FROM tabelle ORDER BY schluessel_teil1,schluessel_teil2,... ; mysql> SELECT ... FROM tabelle ORDER BY schluessel_teil1 DESC,schluessel_teil2 DESC,... ;
© 1995-2005 MySQL AB. All rights reserved.
