Speicher-Engines sammeln tabellenspezifische Statistiken, die der Optimierer verwenden kann. Tabellenstatistiken basieren auf Wertegruppen. Eine Wertegruppe ist eine Menge von Datensätzen mit demselben Schlüsselpräfixwert. Für die Zwecke des Optimierers ist die durchschnittliche Wertegruppengröße eine wichtige Angabe.
MySQL verwendet diese Information,
um zu bestimmen, wie viele Datensätze für jeden
ref
-Zugriff gelesen werden müssen,
um einzuschätzen, wie viele Datensätze ein Teil-Join – oder, genauer, eine Operation der folgenden Form – erzeugt:
(...) JOINtbl_name
ONtbl_name
.key
=expr
Wenn die Durchschnittsgröße der Wertegruppen für einen Index ansteigt, wird der Index für diese beiden Aufgaben zunehmend weniger nützlich, weil auch die durchschnittliche Anzahl von Datensätzen pro Suchvorgang steigt: Damit der Index für Optimierungszwecke gut geeignet ist, wäre es optimal, wenn jeder Indexwert auf eine kleine Anzahl von Datensätzen in der Tabelle abzielt. Hat ein gegebener Indexwert eine hohe Zahl von Datensätzen zum Ergebnis, dann ist sein Nutzen eingeschränkt, und die Wahrscheinlichkeit, dass MySQL ihn verwendet, ist geringer.
Die durchschnittliche Wertegruppengröße bezieht sich auf die
Kardinalität der Tabelle, d. h. die Anzahl der Wertegruppen.
Die SHOW INDEX
-Anweisung zeigt einen
Kardinalitätswert basierend auf N
÷
S
an, wobei
N
die Anzahl der Datensätze in der
Tabelle und S
die durchschnittliche
Wertegruppengröße darstellt. Dieses Verhältnis gibt einen
Näherungswert für die Anzahl der Wertegruppen in der Tabelle
an.
Bei einem Join, der auf dem Vergleichsoperator
<=>
basiert, wird
NULL
nicht anders behandelt als andere Werte:
NULL <=> NULL
(wie
für jeden anderen Wert
N
<=>
N
N
).
Basiert ein Join jedoch auf dem Operator =
,
dann unterscheidet sich NULL
von
Nicht-NULL
-Werten:
ist nicht wahr, wenn
expr1
=
expr2
expr1
oder
expr2
(oder beide)
NULL
sind. Dies wirkt sich auf
ref
-Zugriffe für Vergleiche der Form
aus: MySQL greift
nicht auf die Tabelle zu, wenn der aktuelle Wert von
tbl_name.key
=
expr
expr
NULL
ist,
weil der Vergleich nicht wahr sein kann.
Bei =
-Vergleichen spielt es keine Rolle, wie
viele NULL
-Werte in der Tabelle vorhanden
sind. Der für Optimierungszwecke relevante Wert ist die
Durchschnittsgröße der Gruppe von
Nicht-NULL
-Werten. Allerdings gestattet MySQL
derzeit keine Ermittlung oder Verwendung dieser
Durchschnittsgröße.
Bei MyISAM
-Tabellen haben Sie mit der
Systemvariablen myisam_stats_method
in
eingeschränktem Maße Kontrolle über die Ermittlung der
Tabellenstatistiken. Diese Variable hat zwei mögliche Werte,
die sich wie folgt voneinander unterscheiden:
Wenn myisam_stats_method
nulls_equal
ist, dann werden alle
NULL
-Werte als identisch behandelt
(d. h., sie alle bilden eine Wertegruppe).
Wenn die NULL
-Wertegruppe wesentlich
größer ist als die Durchschnittsgröße der Gruppe der
Nicht-NULL
-Werte, dann erhöht diese
Methode die durchschnittliche Wertegruppengröße. Aufgrund
dessen erscheint der Index dem Optimierer weniger nützlich,
als er es für Joins, die nach
Nicht-NULL
-Werten suchen, tatsächlich
ist. Im Ergebnis kann die
nulls_equal
-Methode also dazu führen,
dass der Optimierer den Index für ref
nicht verwendet, obwohl er es sollte.
Wenn myisam_stats_method
nulls_unequal
ist, werden
NULL
-Werte nicht als identisch
betrachtet. Stattdessen bildet jeder
NULL
-Wert eine separate Wertegruppe der
Größe 1.
Wenn Sie viele NULL
-Werte haben,
verschiebt diese Methode den Durchschnittswert für die
Wertegruppengröße nach unten. Ist der Durchschnittswert
der Gruppe der Nicht-NULL
-Werte hoch,
dann kann dieses Verhalten dazu führen, dass der Optimierer
den Wert des Indexes für Joins überschätzt, die nach
Nicht-NULL
-Werten suchen. Aufgrund dessen
kann der nulls_unequal
-Ansatz dazu
führen, dass der Optimierer diesen Index für
ref
-Suchvorgänge verwendet, obwohl
andere Methoden besser geeignet wären.
Wenn Sie häufig viele Joins benutzen, die
<=>
statt =
verwenden, dann werden NULL
-Werte in
Vergleichen nicht gesondert betrachtet, sondern ein
NULL
-Wert entspricht dem anderen. In diesem
Fall ist nulls_equal
die passende
Statistikmethode.
Die Systemvariable myisam_stats_method
hat
globale und sitzungsbezogene Werte. Das Einstellen des globalen
Werts wirkt sich auf die
MyISAM
-Statistikermittlung bei allen
MyISAM
-Tabellen aus. Im Gegensatz dazu wirkt
der Sitzungswert nur auf Statistiken zur aktuellen
Clientverbindung. Sie können also, indem Sie den Sitzungswert
von myisam_stats_method
einstellen, die
Neuerstellung der Statistiken zu einer Tabelle mit einer
gegebenen Methode erzwingen, ohne dass andere Clients hiervon
beeinträchtigt würden.
Zur Neuerstellung der Tabellenstatistiken können Sie eine der folgenden Methoden benutzen:
Stellen Sie myisam_stats_method
ein und
setzen Sie dann eine CHECK
TABLE
-Anweisung ab.
Führen Sie myisamchk
--stats_method=method_name
--analyze aus.
Ändern Sie die Tabelle so ab, dass die Statistiken veralten
(indem Sie beispielsweise einen Datensatz einfügen und ihn
dann löschen), stellen Sie
myisam_stats_method
ein und setzen Sie
eine ANALYZE TABLE
-Anweisung ab.
Die Verwendung von myisam_stats_method
hat
auch ein paar Nachteile:
Sie können die Ermittlung von Tabellenstatistiken wie gerade
beschrieben erzwingen. Allerdings kann MySQL die Statistiken
auch automatisch sammeln. Wenn beispielsweise während der
Ausführung von Anweisungen für eine Tabelle einige dieser
Anweisungen die Tabelle ändern, ermittelt MySQL unter
Umständen Statistiken. (Dies kann etwa bei Masseneinfüge- oder
-löschoperationen oder bei bestimmten ALTER
TABLE
-Anweisungen der Fall sein.) Wenn dies geschieht,
werden die Statistiken ohne Berücksichtigung des aktuellen
Werts von myisam_stats_method
gesammelt. Wenn
Sie also Statistiken mit einer bestimmten Methode ermitteln,
aber myisam_stats_method
bei einer späteren
automatischen Statistiksammlung auf eine andere Methode gesetzt
wird, dann wird diese andere Methode verwendet.
Es gibt keine Möglichkeit, festzustellen, welche Methode zur
Erzeugung von Statistiken für eine gegebene
MyISAM
-Tabelle verwendet wurde.
myisam_stats_method
gilt nur für
MyISAM
-Tabellen. Die übrigen
Speicher-Engines haben jeweils eigene Methoden zur Ermittlung
von Tabellenstatistiken. Diese ähneln der Methode
nulls_equal
.
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.