Was ist die Bedeutung von gefiltert in MySQL zu erklären?

21

Wie hier in den MySQL-Dokumenten beschrieben :

Die gefilterte Spalte gibt einen geschätzten Prozentsatz der Tabellenzeilen an, die durch die Tabellenbedingung gefiltert werden. Dies bedeutet, dass Zeilen die geschätzte Anzahl der untersuchten Zeilen und Zeilen × gefiltert / 100 die Anzahl der Zeilen anzeigen, die mit vorherigen Tabellen verknüpft werden. Vor MySQL 5.7.3 wird diese Spalte angezeigt, wenn Sie EXPLAIN EXTENDED verwenden. Ab MySQL 5.7.3 ist die erweiterte Ausgabe standardmäßig aktiviert und das Schlüsselwort EXTENDED ist nicht erforderlich.

Ich verstehe es immer noch nicht. Was bedeutet hier "gefiltert"? Welche Informationen können wir aus dieser Spalte erhalten?

Wenn ich beispielsweise mit der Abfrage beginne, werden in einigen Abfragen 100 und in anderen 18 oder weniger als 100 angezeigt.

+-------------+-------+--------+---------+---------+------+----------+
| select_type | table | type   | key     | key_len | rows | filtered |
+-------------+-------+--------+---------+---------+------+----------+
| PRIMARY     | a     | range  | search  | 4       |  174 |   18.00  | <--
| PRIMARY     | b     | eq_ref | PRIMARY | 4       |    1 |   100.00 |
| PRIMARY     | c     | ALL    | PRIMARY | 4       |    1 |   100.00 |

Was ist der wichtigste Punkt, auf den wir aus diesem Wert schließen können?

Sagt es, dass die Spalte nur 18% gefiltert hat? Oder ist der Index / die Abfrage umso besser, je niedriger die Punktzahl ist?

Ich benutze MySQL 5.7

Iman Tumorang
quelle

Antworten:

30

Hier zu filtern bedeutet, eine Bedingung auf eine Reihe von Zeilen anzuwenden, die von type-search als potenzielle Zeilen ausgewählt wurden, und nur Zeilen beizubehalten, die die Bedingung erfüllen:

MySQL wird zunächst versuchen, einen Index zu verwenden, z. B. einen rangeScan Ihres Tisches amit der search-Taste durchzuführen. Es wird geschätzt, dass aus der Verwendung dieses Index 174 Zeilen resultieren. Dies ist die Zahl in rows. Dieser Schritt wird noch nicht als Filtern bezeichnet.

Danach müssen diese 174 Zeilen gegen zusätzliche Bedingungen geprüft werden (normalerweise in Ihrer where-Klausel). MySQL schätzt nun, dass nur 32 Zeilen, also 18% dieser 174 Zeilen, verbleiben, nachdem dieser Filter angewendet wurde. Diese 18% sind der Wert in filtered.

Während es offensichtlich besser ist, 32 statt 174 Zeilen zu haben (wenn Sie diese beispielsweise später joinmit einer anderen Tabelle bearbeiten müssen), hätte Ihnen ein "perfekter" Index diese 32 Zeilen direkt bei der ersten Suche gegeben, was Ihnen die Zeit erspart, sie sich anzusehen und 82% aller potenziellen Zeilen herausfiltern.

Ein niedriger Wert könnte also darauf hinweisen, dass es einen besseren Index geben könnte: z. B. ein vollständiger Tabellenscan mit rows=1000und filtered=0.1%könnte zu einer Indexsuche mit rows=1und werden, filtered=100%wenn Sie einen guten Index hinzufügen.

Auf der anderen Seite, können Sie sehr gut ignorieren vollständig dieses filtered-Wertes (was in den meisten Fällen eine wirklich schlechte Schätzung sowieso), und konzentriert sich auf den anderen , wichtigeren Spalten (vor allem type, keyund extra) , um Ihre Abfrage zu optimieren. Es kann z. B. besser sein, a zu entfernen filesort(z. B. indem ein Index verwendet wird, der die Anforderungen erfüllt order by), auch wenn dies zu einem niedrigeren filteredWert führt. Und eine typeVerbesserung kann zu einer enormen Leistungsverbesserung führen, auch wenn sich diese möglicherweise nicht ändert oder sogar verringert filtered. Im Beispiel oben mit filtered=0.1%, type=allwäre bereits genug , um zu zeigen , dass Sie in der Lage sein könnten , dass die Abfrage zu verbessern , indem Sie einen Index hinzufügen, ohne auf filteredüberhaupt.

Nehmen Sie diesen Wert also nicht zu ernst: Bedeutet nicht, 100dass Ihre Indizes gut sind, und ein niedrigerer Wert weist nicht unbedingt auf schlechte Indizes hin. typeist ein viel besserer Indikator dafür.

Sonneneruption
quelle
1
Danke für die Erklärung. Das erklärt mir sehr viel. Ich denke, es ist nützlich, um den guten Index beizubehalten und auszuwählen
Iman Tumorang
@ImanTumorang Ich habe eine Bemerkung und ein Beispiel hinzugefügt: Nimm diesen Wert nicht zu ernst. Sie können Ihre Anfrage bei einem Blick auf optimieren typeund extra(das ist eine Kunst für sich allein); du könntest ohne leben filtered, aber nicht ohne type.
Sonneneruption
Alles klar. Ich hab es geschafft. Ich habe es bereits in den Mysql Docs gelesen, wie sie sich auf die Leistung auswirken. Vielen Dank für Ihre Erklärung: D
Iman Tumorang
Ein weiterer Tipp: Die gefilterte Berechnung wird für die zuletzt verbundene Tabelle übersprungen. Das heißt, es wird 100% angezeigt, auch wenn tatsächlich Bedingungen vorliegen, die einige der untersuchten Zeilen herausfiltern. Der Grund dafür ist, dass die Schätzung des Filterfaktors etwas kostet. Dies hat keine Auswirkungen auf den Abfrageausführungsplan, wenn er sich in der letzten Tabelle befindet. Daher wird die Berechnung standardmäßig übersprungen.
Bill Karwin