Bei einem einteiligen Index lassen sich die
Indexwertintervalle bequem durch entsprechende Bedingungen in
der WHERE
-Klausel darstellen. Deswegen
sprechen wir in diesem Fall von
Bereichsbedingungen statt von
„Intervallen“.
Die Definition einer Bereichsbedingung für einen einteiligen Index sieht wie folgt aus:
Bei BTREE
- und
HASH
-Indizes ist der Vergleich eines
Schlüsselteils mit einem Konstantenwert eine
Bereichsbedingung, wenn die Operatoren
=
, <=>
,
IN
, IS NULL
oder
IS NOT NULL
verwendet werden.
Bei BTREE
-Indizes ist der Vergleich
eines Schlüsselteils mit einem Konstantenwert eine
Bereichsbedingung, wenn die Operatoren
>
, <
,
>=
, <=
,
BETWEEN
, !=
oder
<>
verwendet werden, oder aber
bei LIKE
'
(wobei
pattern
''
nicht mit einem Jokerzeichen beginnt).
pattern
'
Bei allen Indextypen bilden mehrere Bereichsbedingungen,
die mit OR
oder AND
kombiniert werden, eine Bereichsbedingung.
In den obigen Erläuterungen bezeichnet „Konstantenwert“ eines der folgenden Elemente:
eine Konstante aus dem Abfrage-String
eine Spalte aus einer const
- oder
system
-Tabelle aus demselben Join
das Ergebnis einer unkorrelierten Unterabfrage
jeden Ausdruck, der vollständig aus Unterausdrücken der vorangegangenen Typen zusammengesetzt ist
Es folgen ein paar Beispiele für Abfragen mit
Bereichsbedingungen in der WHERE
-Klausel:
SELECT * FROM t1 WHEREkey_col
> 1 ANDkey_col
< 10; SELECT * FROM t1 WHEREkey_col
= 1 ORkey_col
IN (15,18,20); SELECT * FROM t1 WHEREkey_col
LIKE 'ab%' ORkey_col
BETWEEN 'bar' AND 'foo';
Beachten Sie, dass einige nichtkonstante Werte während der Weitergabephase für Konstanten ihrerseits in Konstanten umgewandelt werden könnten.
MySQL versucht, die Bereichsbedingungen für alle möglichen
Indizes aus der WHERE
-Klausel zu
extrahieren. Während des Extraktionsvorgangs werden
Bedingungen, die nicht zur Bildung der Bereichsbedingung
verwendet werden können, gelöscht; Bedingungen, die
überschneidende Bereiche erzeugen, werden kombiniert;
schließlich werden Bedingungen, die leere Bereiche erzeugen,
entfernt.
Betrachten Sie die folgende Anweisung (hierbei ist
key1
eine indizierte Spalte, während
nonkey
nicht indiziert ist):
SELECT * FROM t1 WHERE (key1 < 'abc' AND (key1 LIKE 'abcde%' OR key1 LIKE '%b')) OR (key1 < 'bar' AND nonkey = 4) OR (key1 < 'uux' AND key1 > 'z');
Der Extraktionsprozess für den Schlüssel
key1
sieht wie folgt aus:
Am Anfang steht die ursprüngliche
WHERE
-Klausel:
(key1 < 'abc' AND (key1 LIKE 'abcde%' OR key1 LIKE '%b')) OR (key1 < 'bar' AND nonkey = 4) OR (key1 < 'uux' AND key1 > 'z')
Nun werden nonkey = 4
und key1
LIKE '%b'
entfernt, weil sie für einen
Bereichsscan nicht verwendet werden können. Die korrekte
Vorgehensweise zur Entfernung besteht darin, sie durch
TRUE
zu ersetzen, damit bei der
Durchführung des Bereichsscans keine passenden
Datensätze übersehen werden. Nach der Ersetzung mit
TRUE
erhalten wir Folgendes:
(key1 < 'abc' AND (key1 LIKE 'abcde%' OR TRUE)) OR (key1 < 'bar' AND TRUE) OR (key1 < 'uux' AND key1 > 'z')
Die folgenden Kollapsbedingungen sind immer wahr oder falsch:
(key1 LIKE 'abcde%' OR TRUE)
ist
immer wahr.
(key1 < 'uux' AND key1 > 'z')
ist immer falsch.
Wenn wir diese Bedingungen durch Konstanten ersetzen, erhalten wir Folgendes:
(key1 < 'abc' AND TRUE) OR (key1 < 'bar' AND TRUE) OR (FALSE)
Durch Entfernen unnötiger TRUE
- und
FALSE
-Konstanten erhalten wir:
(key1 < 'abc') OR (key1 < 'bar')
Die Zusammenfassung überschneidender Intervalle hat die Bedingung zum Ergebnis, die endgültig für den Bereichsscan verwendet werden muss:
(key1 < 'bar')
Im Allgemeinen (und wie auch durch obiges Beispiel
veranschaulicht) ist die für einen Bereichsscan verwendete
Bedingung weniger restriktiv als die
WHERE
-Klausel. MySQL führt eine
zusätzliche Prüfung durch, um Datensätze auszufiltern, die
zwar die Bereichsbedingung erfüllen, nicht aber die
vollständige WHERE
-Klausel.
Der Extraktionsalgorithmus für die Bereichsbedingung kann
verschachtelte AND
- und/oder
OR
-Konstrukte beliebiger Tiefe verarbeiten.
Außerdem hängt seine Ausgabe nicht von der Reihenfolge ab,
in der die Bedingungen in der WHERE
-Klausel
erscheinen.
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.