Die EXPLAIN-Ausgabe deutet darauf hin, dass mein Index nicht verwendet wird

9

Ich habe meine Tabelle mit einem Index nur für done_status (done_status = INT) eingerichtet:

Geben Sie hier die Bildbeschreibung ein

Wenn ich benutze:

EXPLAIN SELECT * FROM reminder  WHERE done_status=2

Ich bekomme das zurück:

id select_type Tabellentyp möglichen_Tasten key key_len ref Zeilen Extra
1 EINFACHE Erinnerung ALL done_status NULL NULL NULL 5 Verwenden von where

Aber wenn ich diesen Befehl gebe:

EXPLAIN SELECT * FROM reminder  WHERE done_status=1

Ich bekomme folgendes zurück:

id select_type Tabellentyp möglichen_Tasten key key_len ref Zeilen Extra
1 EINFACHE Erinnerung ref done_status done_status 4 const 2   

Das EXPLAINzeigt mir, dass es 5 Zeilen verwendet, das zweite Mal 2 Zeilen.

Ich glaube nicht, dass der Index verwendet wird. Wenn ich ihn beim ersten Mal richtig verstanden habe, sollte er mir 3 Zeilen geben. Was mache ich falsch?

SHOW INDEX FROM reminder::

Tabelle Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Kommentar Index_comment
Erinnerung 1 done_status 1 done_status A 5 NULL NULL BTREE

erklären erweitert:

id select_type Tabellentyp möglichen_Tasten key key_len ref Zeilen gefiltert Extra
1 EINFACHE Erinnerung ref done_status done_status 4 const 2 100.00

show warnings zeigte nichts von Interesse.

TasostheGreat
quelle
Vertrauen Sie mir, der Index funktioniert. Aber ich kann nichts leicht in Ihrem Screenshot sehen - können Sie einen "Show-Index von Ihrem Tisch" machen
Ja, meine Frage wurde bearbeitet
Bitte verwenden Sie glorify \ G für das Schema und erklären Sie das
Planergebnis
Aus Interesse können Sie mit einem "EXPLAIN Extended" und einem "Show Warnungen" wiederholen. Dies zeigt die tatsächliche Auswahl von SQL MySQL
@ajreal was ist verherrlichen?

Antworten:

4

Sie verstehen falsch, was das Feld "Zeilen" ist. Es ist die Anzahl der Zeilen, die MySQL schätzt, um gelesen zu werden, um Ihre Anfrage zu erfüllen. Dieser Wert kann sehr ungenau sein. Dies bedeutet nicht, dass dies die Anzahl der Zeilen im Ergebnis ist - oder die tatsächliche Anzahl der von MySQL gelesenen Zeilen


quelle
So? Wo habe ich gesagt, dass es tut? Was der Optimierer auswählt, hängt davon ab? Der Index funktioniert immer noch.
@ajreal Das heißt aber nicht, dass der Index kaputt ist. Nur der Optimierer wählt (in seinem Kopf) den effizientesten Weg, um die Daten abzufragen. Ich nahm an, dass das OP erwartete, dass die Zeilenspalte in EXPLAIN genau ist. Dies bedeutet nicht, dass der Index fehlerhaft ist - nur, dass MySQL ihn (wahrscheinlich) nicht verwendet.
1
@ajreal: Mir fehlt etwas in deinen Punkten. Die Zeilenspalte einer EXPLAIN hat nichts mit Indizes zu tun, oder? MySQL verwendet den Index nicht (möglicherweise befinden sich alle Daten auf einer einzigen Seite). Nicht sicher, ob ich Ihren Standpunkt verstehe? Die Abfrageoptimierung für eine Tabelle mit 5 Zeilen führt zu einigen "ungeraden" Ergebnissen, da es so gut wie keine Rolle spielt, wie Sie optimieren.
In diesem Fall, wen interessiert es, welchen Index der Optimierer wählt? An dem Index selbst ist nichts auszusetzen, da der Optimierer das Gefühl hatte, ihn nicht zu benötigen - was macht das aus?
3

In der ersten Ausführungsebene wird der Index nicht mit Sicherheit verwendet.
Es kann sein, dass die information_schema.statistics im Index nach einigen Schreibvorgängen die Daten nicht einholt oder dass lange nicht auf die Tabelle zugegriffen wurde.

wie hier erklärt: - Woher liest der MySQL Query Optimizer Indexstatistiken?

Für den zweiten Ausführungsplan scheint information_schema.statistics das NULL-Kardinalitätsproblem bereits aufzuholen und zu beheben.

Daher wird die Abfrage gemäß dem Indexoptimierer ausgeführt.

Für Tabellen mit kleinen Zeilen spielt es keine Rolle.
Die Daten werden jedoch wachsen. Entwickler sollten dies immer überprüfen
und die erforderliche Analysetabelle durchführen, wenn die Kardinalität der Begegnung im Index null ist.

ajreal
quelle
0

Der erste Ausführungsplan verwendet keinen Index.

Von der MySQL-Referenzwebsite :

Manchmal verwendet MySQL keinen Index, selbst wenn einer verfügbar ist. Ein Umstand, unter dem dies auftritt, ist, wenn der Optimierer schätzt, dass für die Verwendung des Index MySQL auf einen sehr großen Prozentsatz der Zeilen in der Tabelle zugreifen muss. (In diesem Fall ist ein Tabellenscan wahrscheinlich viel schneller, da weniger Suchvorgänge erforderlich sind.) Wenn eine solche Abfrage jedoch LIMIT verwendet, um nur einige der Zeilen abzurufen, verwendet MySQL ohnehin einen Index, da dieser viel schneller gefunden werden kann die wenigen Zeilen, die im Ergebnis zurückgegeben werden sollen.

Wenn Ihre Tabelle nur 5 Zeilen enthält und Ihre Abfrage 3 davon auswählt, geht das MySQL-Optimierungsprogramm davon aus, dass das Scannen der gesamten Tabelle effizienter ist.

Matthew Sammut
quelle