Einführung MySQL bietet einen EXPLAIN-Befehl, der SELECT-Anweisungen analysiert und detaillierte Informationen zur SELECT-Ausführung ausgibt, damit Entwickler diese optimieren können. Der EXPLAIN-Befehl ist sehr einfach zu verwenden. Fügen Sie einfach „Explain“ vor der SELECT-Anweisung hinzu. Beispiel: ERKLÄREN SIE: SELECT * aus Benutzerinfo, WO ID < 300; Vorbereiten Um die Verwendung von EXPLAIN zu demonstrieren, müssen wir zunächst zwei Testtabellen erstellen und die entsprechenden Daten hinzufügen: CREATE TABLE `user_info` ( `id` BIGINT(20) NICHT NULL AUTO_INCREMENT, `name` VARCHAR(50) NICHT NULL STANDARD '', `Alter` INT(11) DEFAULT NULL, Primärschlüssel (`id`), SCHLÜSSEL `name_index` (`name`) ) ENGINE = InnoDB STANDARD-ZEICHENSATZ = utf8 INSERT INTO user_info (Name, Alter) VALUES ('xys', 20); INSERT INTO user_info (Name, Alter) VALUES ('a', 21); INSERT INTO user_info (Name, Alter) VALUES ('b', 23); INSERT INTO user_info (Name, Alter) VALUES ('c', 50); INSERT INTO user_info (Name, Alter) VALUES ('d', 15); INSERT INTO user_info (Name, Alter) VALUES ('e', 20); INSERT INTO user_info (Name, Alter) VALUES ('w', 21); INSERT INTO user_info (Name, Alter) VALUES ('g', 23); INSERT INTO user_info (Name, Alter) VALUES ('h', 50); INSERT INTO user_info (Name, Alter) VALUES ('i', 15); CREATE TABLE `order_info` ( `id` BIGINT(20) NICHT NULL AUTO_INCREMENT, `Benutzer-ID` BIGINT(20) DEFAULT NULL, `Produktname` VARCHAR(50) NICHT NULL STANDARD '', `Produzent` VARCHAR(30) DEFAULT NULL, Primärschlüssel (`id`), SCHLÜSSEL `user_product_detail_index` (`Benutzer-ID`, `Produktname`, `Produkthersteller`) ) ENGINE = InnoDB STANDARD-ZEICHENSATZ = utf8 INSERT INTO order_info (Benutzer-ID, Produktname, Hersteller) VALUES (1, „p1“, „WHH“); INSERT INTO order_info (Benutzer-ID, Produktname, Hersteller) VALUES (1, 'p2', 'WL'); INSERT INTO order_info (Benutzer-ID, Produktname, Hersteller) VALUES (1, „p1“, „DX“); INSERT INTO order_info (Benutzer-ID, Produktname, Hersteller) VALUES (2, 'p1', 'WHH'); INSERT INTO order_info (Benutzer-ID, Produktname, Hersteller) VALUES (2, 'p5', 'WL'); INSERT INTO order_info (Benutzer-ID, Produktname, Hersteller) VALUES (3, 'p3', 'MA'); INSERT INTO order_info (Benutzer-ID, Produktname, Hersteller) VALUES (4, 'p1', 'WHH'); INSERT INTO order_info (Benutzer-ID, Produktname, Hersteller) VALUES (6, 'p1', 'WHH'); INSERT INTO order_info (Benutzer-ID, Produktname, Hersteller) VALUES (9, 'p8', 'TE'); EXPLAIN-Ausgabeformat Die Ausgabe des EXPLAIN-Befehls lautet ungefähr wie folgt: mysql> erklären select * from user_info where id = 2\G *************************** 1. Reihe *************************** ID: 1 select_type: EINFACH Tabelle: Benutzerinformationen Partitionen: NULL Typ: const mögliche Schlüssel: PRIMARY Schlüssel: PRIMARY Schlüssellänge: 8 Verweis: const Reihen: 1 gefiltert: 100,00 Extra: NULL 1 Zeile im Satz, 1 Warnung (0,00 Sek.) Die einzelnen Spalten haben folgende Bedeutung:
Schauen wir uns als Nächstes einige der wichtigeren Felder an. Wählen Sie Typ
Der häufigste Abfragetyp sollte SIMPLE sein. Wenn unsere Abfrage beispielsweise keine Unterabfrage oder UNION-Abfrage hat, ist sie normalerweise vom Typ SIMPLE, zum Beispiel: mysql> erklären select * from user_info where id = 2\G *************************** 1. Reihe *************************** ID: 1 select_type: EINFACH Tabelle: Benutzerinformationen Partitionen: NULL Typ: const mögliche Schlüssel: PRIMARY Schlüssel: PRIMARY Schlüssellänge: 8 Verweis: const Reihen: 1 gefiltert: 100,00 Extra: NULL 1 Zeile im Satz, 1 Warnung (0,00 Sek.) Wenn wir eine UNION-Abfrage verwenden, sieht die EXPLAIN-Ausgabe ungefähr wie folgt aus: mysql> ERKLÄREN (SELECT * FROM user_info WHERE id IN (1, 2, 3)) -> UNION -> (SELECT * FROM Benutzerinfo WHERE ID IN (3, 4, 5)); +----+--------------+------------+------------+-------+---------------+--------+---------+---------+------+------+------+-----------------+ | ID | Auswahltyp | Tabelle | Partitionen | Typ | mögliche Schlüssel | Schlüssel | Schlüssellänge | Ref. | Zeilen | gefiltert | Extra | +----+--------------+------------+------------+-------+---------------+--------+---------+---------+------+------+------+-----------------+ | 1 | PRIMARY | Benutzerinfo | NULL | Bereich | PRIMARY | PRIMARY | 8 | NULL | 3 | 100,00 | Verwenden von „where“ | | 2 | UNION | Benutzerinfo | NULL | Bereich | PRIMARY | PRIMARY | 8 | NULL | 3 | 100,00 | Verwenden von „where“ | | NULL | UNION-ERGEBNIS | <union1,2> | NULL | ALL | NULL | NULL | NULL | NULL | NULL | NULL | Temporäre | verwenden | +----+--------------+------------+------------+-------+---------------+--------+---------+---------+------+------+------+-----------------+ 3 Zeilen im Satz, 1 Warnung (0,00 Sek.) Tisch Gibt die Tabelle oder abgeleitete Tabelle an, die in der Abfrage enthalten ist. Typ Das Typfeld ist wichtig, da es eine wichtige Grundlage für die Beurteilung der Effizienz der Abfrage bietet. Über das Typfeld können wir beurteilen, ob es sich bei der Abfrage um einen vollständigen Tabellenscan oder einen Indexscan handelt. Typ Gängige Typen Übliche Werte für Typ sind:
mysql> erklären select * from user_info where id = 2\G *************************** 1. Reihe *************************** ID: 1 select_type: EINFACH Tabelle: Benutzerinformationen Partitionen: NULL Typ: const mögliche Schlüssel: PRIMARY Schlüssel: PRIMARY Schlüssellänge: 8 Verweis: const Reihen: 1 gefiltert: 100,00 Extra: NULL 1 Zeile im Satz, 1 Warnung (0,00 Sek.)
mysql> EXPLAIN SELECT * FROM Benutzerinfo, Bestellinfo WHERE Benutzerinfo.id = Bestellinfo.Benutzerid\G *************************** 1. Reihe *************************** ID: 1 select_type: EINFACH Tabelle: Bestellinfo Partitionen: NULL Typ: Index mögliche Schlüssel: Benutzer-Produktdetailindex Schlüssel: user_product_detail_index Schlüssellänge: 314 Ref: NULL Reihen: 9 gefiltert: 100,00 Extra: Verwenden von „where“; Verwenden von „index“ *************************** 2. Reihe *************************** ID: 1 select_type: EINFACH Tabelle: Benutzerinformationen Partitionen: NULL Typ: eq_ref mögliche Schlüssel: PRIMARY Schlüssel: PRIMARY Schlüssellänge: 8 Referenz: test.order_info.user_id Reihen: 1 gefiltert: 100,00 Extra: NULL 2 Zeilen im Satz, 1 Warnung (0,00 Sek.)
Im folgenden Beispiel wird beispielsweise die Abfrage vom Typ „Ref“ verwendet: mysql> EXPLAIN SELECT * FROM Benutzerinfo, Bestellinfo WHERE Benutzerinfo.id = Bestellinfo.Benutzerid AND Bestellinfo.Benutzerid = 5\G *************************** 1. Reihe *************************** ID: 1 select_type: EINFACH Tabelle: Benutzerinformationen Partitionen: NULL Typ: const mögliche Schlüssel: PRIMARY Schlüssel: PRIMARY Schlüssellänge: 8 Verweis: const Reihen: 1 gefiltert: 100,00 Extra: NULL *************************** 2. Reihe *************************** ID: 1 select_type: EINFACH Tabelle: Bestellinfo Partitionen: NULL Typ: ref mögliche Schlüssel: Benutzer-Produktdetailindex Schlüssel: user_product_detail_index Schlüssellänge: 9 Verweis: const Reihen: 1 gefiltert: 100,00 Extra: Index verwenden 2 Zeilen im Satz, 1 Warnung (0,01 Sek.)
Wenn der Typ ein Bereich ist, ist das Ref-Feld in der EXPLAIN-Ausgabe NULL und das Key_len-Feld ist der längste in der Abfrage verwendete Index. Das folgende Beispiel ist beispielsweise eine Bereichsabfrage: mysql> ERKLÄREN AUSWÄHLEN * -> VON Benutzerinfo -> WO id ZWISCHEN 2 UND 8 \G *************************** 1. Reihe *************************** ID: 1 select_type: EINFACH Tabelle: Benutzerinformationen Partitionen: NULL Typ: Bereich mögliche Schlüssel: PRIMARY Schlüssel: PRIMARY Schlüssellänge: 8 Ref: NULL Reihen: 7 gefiltert: 100,00 Extra: Verwenden von „where“ 1 Zeile im Satz, 1 Warnung (0,00 Sek.)
Der Indextyp wird normalerweise angezeigt, wenn die abzufragenden Daten direkt im Indexbaum abgerufen werden können, ohne dass die Daten gescannt werden müssen. In diesem Fall wird im Feld „Extra“ „Index wird verwendet“ angezeigt. Zum Beispiel: mysql> EXPLAIN SELECT name FROM Benutzerinfo \G *************************** 1. Reihe *************************** ID: 1 select_type: EINFACH Tabelle: Benutzerinformationen Partitionen: NULL Typ: Index mögliche Schlüssel: NULL Schlüssel: name_index Schlüssellänge: 152 Ref: NULL Reihen: 10 gefiltert: 100,00 Extra: Index verwenden 1 Zeile im Satz, 1 Warnung (0,00 Sek.) Im obigen Beispiel ist das von uns abgefragte Namensfeld zufällig ein Index, sodass wir die Daten direkt aus dem Index abrufen können, um die Abfrageanforderungen zu erfüllen, ohne die Daten in der Tabelle abzufragen. Daher ist in diesem Fall der Wert von Typ Index und der Wert von Extra ist Index verwenden.
Nachfolgend sehen Sie ein Beispiel für einen vollständigen Tabellenscan. Sie können sehen, dass im vollständigen Tabellenscan sowohl die Possible_Keys- als auch die Key-Felder NULL sind, was darauf hinweist, dass kein Index verwendet wird. Außerdem sind die Zeilen sehr groß, sodass die Gesamtabfrageeffizienz sehr gering ist. mysql> EXPLAIN SELECT Alter FROM Benutzerinfo WHERE Alter = 20 \G *************************** 1. Reihe *************************** ID: 1 select_type: EINFACH Tabelle: Benutzerinformationen Partitionen: NULL Typ: ALLE mögliche Schlüssel: NULL Schlüssel: NULL key_len: NULL Ref: NULL Reihen: 10 gefiltert: 10.00 Extra: Verwenden von „where“ 1 Zeile im Satz, 1 Warnung (0,00 Sek.) Leistungsvergleich von Typ Im Allgemeinen ist das Leistungsverhältnis zwischen den verschiedenen Typen wie folgt: ALLE <Index <Bereich ~Index_Merge <Ref <Eq_Ref <const <System Der Typ „ALL“ ist der langsamste, da es sich um einen vollständigen Tabellenscan unter denselben Abfragebedingungen handelt. Obwohl die Abfrage vom Typ „Index“ nicht die gesamte Tabelle durchsucht, durchsucht sie alle Indizes und ist daher etwas schneller als der Typ „ALL“. Die folgenden Typen verwenden alle Indizes zum Abfragen von Daten, sodass einige oder die meisten Daten gefiltert werden können und die Abfrageeffizienz relativ hoch ist. mögliche Schlüssel Possible_keys gibt die Indizes an, die MySQL bei Abfragen verwenden kann. Beachten Sie, dass selbst wenn einige Indizes in Possible_keys erscheinen, dies nicht bedeutet, dass dieser Index tatsächlich von MySQL verwendet wird. Die spezifischen Indizes, die MySQL bei Abfragen verwendet, werden durch das Schlüsselfeld bestimmt. Schlüssel Dieses Feld ist der Index, den MySQL tatsächlich in der aktuellen Abfrage verwendet. Schlüssellänge Gibt die Anzahl der vom Abfrageoptimierer verwendeten Bytes an. Mit diesem Feld kann ausgewertet werden, ob der zusammengesetzte Index vollständig verwendet wird oder nur die Felder ganz links verwendet werden. Zeichenfolge
Werttyp:
Zeittyp
Feldattribute: Das NULL-Attribut belegt ein Byte. Wenn ein Feld NICHT NULL ist, hat es dieses Attribut nicht. Betrachten wir zwei einfache Beispiele: mysql> EXPLAIN SELECT * FROM order_info WHERE user_id < 3 AND product_name = 'p1' AND productor = 'WHH' \G *************************** 1. Reihe *************************** ID: 1 select_type: EINFACH Tabelle: Bestellinfo Partitionen: NULL Typ: Bereich mögliche Schlüssel: Benutzer-Produktdetailindex Schlüssel: user_product_detail_index Schlüssellänge: 9 Ref: NULL Reihen: 5 gefiltert: 11.11 Extra: Verwenden von „where“; Verwenden von „index“ 1 Zeile im Satz, 1 Warnung (0,00 Sek.) Das obige Beispiel fragt den angegebenen Inhalt aus der Tabelle order_info ab. Aus der Anweisung zur Tabellenerstellung können wir erkennen, dass die Tabelle order_info einen gemeinsamen Index hat: SCHLÜSSEL `user_product_detail_index` (`Benutzer-ID`, `Produktname`, `Produkthersteller`) In der Abfrage WHERE user_id < 3 AND product_name = 'p1' AND productor = 'WHH' wird jedoch zuerst die user_id-Bereichsabfrage ausgeführt. Gemäß dem Prinzip des ganz linken Präfixabgleichs wird der Indexabgleich beendet, wenn eine Bereichsabfrage gefunden wird. Daher ist user_id tatsächlich das einzige Indexfeld, das wir verwenden. Daher ist in EXPLAIN die angezeigte key_len 9. Da das user_id-Feld BIGINT ist, belegt es 8 Bytes und das NULL-Attribut belegt ein Byte, sodass die Gesamtsumme 9 Bytes beträgt. Wenn wir das user_id-Feld in BIGINT(20) NOT NULL DEFAULT '0' ändern, sollte die key_length 8 sein. Aufgrund des Prinzips des ganz linken Präfixabgleichs verwendet unsere Abfrage nur das Feld user_id des gemeinsamen Index, sodass die Effizienz nicht hoch ist. Schauen wir uns das nächste Beispiel an: mysql> EXPLAIN SELECT * FROM order_info WHERE user_id = 1 AND product_name = 'p1' \G; *************************** 1. Reihe *************************** ID: 1 select_type: EINFACH Tabelle: Bestellinfo Partitionen: NULL Typ: ref mögliche Schlüssel: Benutzer-Produktdetailindex Schlüssel: user_product_detail_index Schlüssellänge: 161 Verweis: konstant, konstant Reihen: 2 gefiltert: 100,00 Extra: Index verwenden 1 Zeile im Satz, 1 Warnung (0,00 Sek.) In dieser Abfrage haben wir keine Bereichsabfrage verwendet und der Wert von key_len ist 161. Warum? Weil in unserer Abfragebedingung WHERE user_id = 1 AND product_name = 'p1' nur die ersten beiden Felder im gemeinsamen Index verwendet werden, also keyLen(user_id) + keyLen(product_name) = 9 + 50 * 3 + 2 = 161 Reihen Zeilen sind ebenfalls ein wichtiges Feld. Basierend auf den Statistiken schätzt der MySQL-Abfrageoptimierer die Anzahl der Zeilen, die SQL scannen muss, um den Ergebnissatz zu finden. Extra Im Feld „Extra“ werden in „EXplain“ zahlreiche Zusatzinformationen angezeigt. Die häufigsten sind die folgenden:
Wenn „Using Filesort“ im Extra-Modus ist, bedeutet dies, dass MySQL zusätzliche Sortiervorgänge benötigt und den Sortiereffekt nicht über die Indexreihenfolge erzielen kann. Generell wird empfohlen, „Using Filesort“ zu optimieren und zu entfernen, da solche Abfragen viele CPU-Ressourcen verbrauchen. Beispielsweise das folgende Beispiel: mysql> EXPLAIN SELECT * FROM Bestellinfo ORDER BY Produktname \G *************************** 1. Reihe *************************** ID: 1 select_type: EINFACH Tabelle: Bestellinfo Partitionen: NULL Typ: Index mögliche Schlüssel: NULL Schlüssel: user_product_detail_index Schlüssellänge: 253 Ref: NULL Reihen: 9 gefiltert: 100,00 Extra: Index verwenden; Filesort verwenden 1 Zeile im Satz, 1 Warnung (0,00 Sek.) Unser Index ist SCHLÜSSEL `user_product_detail_index` (`Benutzer-ID`, `Produktname`, `Produkthersteller`) Die obige Abfrage ist jedoch nach Produktname sortiert, sodass der Index nicht zur Optimierung verwendet werden kann, was zur Verwendung von Filesort führt. Wenn wir die Sortierbasis in ORDER BY user_id, product_name ändern, wird Using filesort nicht angezeigt. Beispiel: mysql> EXPLAIN SELECT * FROM Bestellinfo ORDER BY Benutzer-ID, Produktname \G *************************** 1. Reihe *************************** ID: 1 select_type: EINFACH Tabelle: Bestellinfo Partitionen: NULL Typ: Index mögliche Schlüssel: NULL Schlüssel: user_product_detail_index Schlüssellänge: 253 Ref: NULL Reihen: 9 gefiltert: 100,00 Extra: Index verwenden 1 Zeile im Satz, 1 Warnung (0,00 Sek.)
"Abdeckender Index-Scan" bedeutet, dass die Abfrage die erforderlichen Daten im Indexbaum finden kann, ohne die Tabellendatendatei zu scannen, was häufig auf eine gute Leistung hinweist
Die Abfrage verwendet temporäre Tabellen, die normalerweise in Sortier-, Gruppierungs- und Mehrtabellenverknüpfungssituationen vorkommen. Die Abfrageeffizienz ist nicht hoch. Es wird empfohlen, sie zu optimieren. Zusammenfassen Das Obige ist der vollständige Inhalt dieses Artikels. Ich hoffe, dass der Inhalt dieses Artikels einen gewissen Lernwert für Ihr Studium oder Ihre Arbeit hat. Vielen Dank für Ihre Unterstützung von 123WORDPRESS.COM. Das könnte Sie auch interessieren:
|
<<: Das WeChat-Applet realisiert den Neun-Quadrat-Rastereffekt
>>: Lösen Sie das Problem, dass die Zeitzone in der Linux-Umgebung nicht eingestellt werden kann
Phänomen: Führen Sie ein Image aus, zum Beispiel ...
Dieser Artikel basiert auf dem Free Code Camp Bas...
Code kopieren Der Code lautet wie folgt: <hr S...
=================================================...
Technischer Hintergrund Latex ist ein unverzichtb...
Installieren Sie antd-mobile Globaler Import npm ...
Wie lange ist es her, dass ich meine Kolumne aktu...
In diesem Artikelbeispiel wird der spezifische Co...
Einführung Es ist nicht nötig, Redis im Detail vo...
Inhaltsverzeichnis brauchen: Funktionspunkte Rend...
Inhaltsverzeichnis Übergeordnete Komponente kommu...
Inhaltsverzeichnis 1. JavaScript kann alle HTML-E...
My97DatePicker ist ein sehr flexibles und benutze...
Inhaltsverzeichnis Installationsvoraussetzungen S...
Nachfragehintergrund Als statistische Schnittstel...