Heim  >  Artikel  >  Datenbank  >  Dieser Artikel hilft Ihnen, den MySQL-Ausführungsplan schnell zu verstehen

Dieser Artikel hilft Ihnen, den MySQL-Ausführungsplan schnell zu verstehen

青灯夜游
青灯夜游nach vorne
2022-10-21 20:45:031519Durchsuche

Dieser Artikel hilft Ihnen, den MySQL-Ausführungsplan schnell zu verstehen

Normalerweise werden langsame Abfrageanweisungen SQL语句时会使用EXPLAIN命令来查看SQL语句的执行计划,通过返回的信息,可以了解到Mysql优化器是如何执行SQL abgefragt, und die Analyse kann uns dabei helfen, Optimierungsideen bereitzustellen.

1. EXPLAIN-Funktion

Der EXPLAIN-Befehl wird hauptsächlich zum Anzeigen des Ausführungsplans von SQL-Anweisungen verwendet. Dieser Befehl kann die Ausführung von SQL-Abfrageanweisungen durch den Optimierer simulieren und uns beim Schreiben und Optimieren von SQL helfen. Welche spezifischen Informationen können uns also bei der Optimierung von SQL helfen?

  • Tabellenlesereihenfolge

  • Operationstyp des Datenlesevorgangs

  • Welche Indizes können verwendet werden?

  • Welche Indizes werden tatsächlich verwendet?

    Wie viele Zeilen in Jede Tabelle wird vom Optimierer abgefragt , die Liste enthält 12 Felder und die Felder beschreiben gemeinsam, wie SQL im Ausführungsplan ausgeführt wird. Die folgende Liste beschreibt die Bedeutung der Felder in der Ausführungsplantabelle im Detail:
  • Feldname
  • Beschreibung

id

Die Sequenznummer der Select-Anweisungsabfrage, die die Lesereihenfolge bestimmt der Tabelle

select_type Dieser Artikel hilft Ihnen, den MySQL-Ausführungsplan schnell zu verstehen

Der Typ der Abfrage, d

Typ

Zugriffstypmögliche_SchlüsselVerwendbare Indizes. Wenn für das an der Abfrage beteiligte Feld ein Index vorhanden ist, wird der Index aufgelistet, aber möglicherweise nicht tatsächlich von der Abfrage verwendet. Wenn dieses Feld null ist, der Feldschlüssel jedoch nicht null ist, bedeutet diese Situation, dass bei der Suche kein sekundärer Indexbaum verwendet werden kann, der sekundäre Index jedoch die Felder enthält, die abgefragt werden müssen, sodass der Clustered-Index (Clustered-Index) vorhanden ist ) wird nicht mehr durchsucht, stattdessen wird der sekundäre Indexbaum gescannt (der sekundäre Indexbaum ist relativ klein), und zu diesem Zeitpunkt ist der allgemeine Zugriffstyp Index und der gesamte Indexbaum wird gescannt . keyDer vom eigentlichen Scan verwendete Index. Wenn es null ist, wird der Index nicht verwendet. Wenn in der Abfrage ein abdeckender Index verwendet wird, erscheint der Index nur in der Schlüsselliste. Diese Spalte kann verwendet werden, um die Länge des in der Abfrage verwendeten Index zu berechnen. Je kürzer die Länge, desto besser ist der von key_len angezeigte Wert die maximal mögliche Länge des Indexfelds und nicht die tatsächlich verwendete Länge. Das heißt, key_len basiert auf der Tabelle. Die Definition wird berechnet und nicht aus der Tabelle abgerufen. ref zeigt an, welche Spalte des Index verwendet wird. Wenn möglich, handelt es sich um eine Konstante. Welche Spalten oder Konstanten werden zum Ermitteln des Werts in der Indexspalte verwendet? Anzahl der Zeilen; gefiltertDer Prozentsatz der verbleibenden Daten nach der Filterung nach Suchbedingungen. ExtraEnthält zusätzliche Informationen, die nicht für die Anzeige in anderen Spalten geeignet sind, aber sehr wichtig sind3. Schlüsselfeldanalyse (1) idTypnameBeschreibungID ist die gleichAusführungsreihenfolge von oben nach unten WeiterID ist unterschiedlichWenn es sich um eine Unterabfrage handelt, wird die Sequenznummer der ID erhöht. Je größer der ID-Wert, desto höher die Priorität, desto früher ausgeführtid ist gleich, aber unterschiedlich und existiert gleichzeitigWenn die ID gleich ist, können Sie sie als Gruppe betrachten und nacheinander von oben nach unten ausführen Je höher der ID-Wert, desto höher die Priorität und desto früher wird sie ausgeführt

(2) select_type

ist der Operationstyp des Datenlesevorgangs. Es gibt die folgenden Typen:

Sequenz der Ausführung der Select-Anweisung Abfrage-Nr., enthält eine Reihe von Zahlen, die die Reihenfolge angeben, in der Auswahlklauseln oder Operationstabellen in der Abfrage ausgeführt werden. Es gibt drei Situationen:
primärUnterabfrageabhängige Unterabfragederivedabhängige UnionTypnameBeschreibungN> gibt an, dass es sich um eine temporäre Tabelle handelt, und das folgende N ist die ID im Ausführungsplan, was angibt, dass die Ergebnisse aus dieser Abfrage generiert werden. M,N> ähnelt N> und ist ebenfalls temporär Tabelle, die darstellt: Dieses Ergebnis stammt aus der Ergebnismenge mit der ID M,N der Union-Abfrage.
Typname Beschreibung
Einfache Auswahlabfrage, Abfrage nicht enthalten Unterabfragen oder Unions;
Wenn die Abfrage komplexe Unterabfragen enthält, wird die äußerste Abfrage markiert;
enthält Unterabfragen in der Select- oder Where-Liste;
Das erste SELECT in der Unterabfrage hängt von der äußeren Abfrage ab. Das heißt, die Unterabfrage hängt von den Ergebnissen der äußeren Abfrage ab.
Die in der Von-Liste enthaltenen Unterabfragen werden als DERIVED (abgeleitete Tabellen) markiert. MySQL führt diese Unterabfragen rekursiv aus und fügt die Ergebnisse in die temporäre Tabelle ein Erscheint nach der Union, wird sie als Union markiert. Wenn Union in der Unterabfrage der From-Klausel enthalten ist, wird die äußere Auswahl als DERIVED markiert Union-Zusammenführung: Holen Sie sich die Ergebnisse der ausgewählten Abfrage im Satz); basierend auf den Daten in der temporären Tabelle abgeglichen.
UNION Die zweite oder nachfolgende Abfrageanweisung in UNION hängt von der externen Abfrage ab Was hier angezeigt wird, ist der Alias. Wenn es keine Operation für die Datentabelle gibt, wird dieser als Null angezeigt oder er kann einer der folgenden sein:

N>Diese Zeile bezieht sich auf den Wert N der Ergebnis-ID der Zeile mit der materialisierten Unterabfrage.

(4)Partitionen

Die Abfrage stimmt mit den Partitionen der Datensätze überein. Der Wert NULL wird für nicht partitionierte Tabellen verwendet. NULL用于非分区表。

(5)type

依次从好到差:

system>const>eq_ref>ref>ref_or_null>range>index>ALL

除了all之外,其他的type都可以使用到索引,除了index_merge之外,其他的type只可以用到一个索引。

我们自己创建一系列表来实验下:

Dieser Artikel hilft Ihnen, den MySQL-Ausführungsplan schnell zu verstehen

Dieser Artikel hilft Ihnen, den MySQL-Ausführungsplan schnell zu verstehen

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for goods
-- ----------------------------
DROP TABLE IF EXISTS `goods`;
CREATE TABLE `goods`  (
  `id` int(11) NOT NULL,
  `sn` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of goods
-- ----------------------------
INSERT INTO `goods` VALUES (1, 'sn123456', '衣服');

-- ----------------------------
-- Table structure for sku
-- ----------------------------
DROP TABLE IF EXISTS `sku`;
CREATE TABLE `sku`  (
  `id` int(11) NOT NULL,
  `goods_id` int(11) NOT NULL,
  `status` int(11) NOT NULL,
  `deleted` int(11) NOT NULL,
  `barcode` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE INDEX `index_2`(`name`) USING BTREE,
  INDEX `index_1`(`goods_id`, `status`, `deleted`, `barcode`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of sku
-- ----------------------------
INSERT INTO `sku` VALUES (1, 1, 1, 0, 'kt123456', '黑色');

SET FOREIGN_KEY_CHECKS = 1;

system

表只有一行记录(等于系统表),这是 const 类型的特例,平时不会出现,这个也可忽略不计;

const

表示通过索引一次就找到了,const 用于比较 primary key 或者 unique 索引。因为只匹配一行记录,所以很快。 如果将主键置于 where 列表中,mysql 就能将该查询转换成一个常量;

EXPLAIN SELECT * FROM sku WHERE id=1;复制代码

Dieser Artikel hilft Ihnen, den MySQL-Ausführungsplan schnell zu verstehen

eq_ref

唯一性索引扫描,对于每一个索引键,表中只有一条记录与之匹配,常用于主键或唯一索引扫描;此类型通常出现在多表的 join 等值查询,表示对于前表的每一个结果,都只能匹配到后表的一行结果,查询效率较高。

EXPLAIN SELECT * FROM sku,goods WHERE sku.goods_id=goods.id;

Dieser Artikel hilft Ihnen, den MySQL-Ausführungsplan schnell zu verstehen

ref

非唯一性索引扫描,返回匹配某个单独值得所有行,本质上也是一种索引访问,它返回所有匹配某个单独值的行,然而,它可能会找到多个符合条件的行,所以它应该属于查找和扫描的混合体;

EXPLAIN SELECT * FROM sku WHERE goods_id=1;

Dieser Artikel hilft Ihnen, den MySQL-Ausführungsplan schnell zu verstehen

ref_or_null

二级索引等值比较同时限定 is null 。

EXPLAIN SELECT * FROM sku WHERE name='123456' or name IS NULL;

Dieser Artikel hilft Ihnen, den MySQL-Ausführungsplan schnell zu verstehen

range

只检索给定范围的行,使用一个索引来选择行,key列显示使用哪个索引,一般就是在你的 where 语句中出现了 between、、in 等的查询;这种范围索引扫描比全表扫描要好,因为它只需要开始于索引的某一个点,结束于另一个点,不用扫描全部索引;

EXPLAIN SELECT * FROM sku WHERE id BETWEEN 1 and 10;

Dieser Artikel hilft Ihnen, den MySQL-Ausführungsplan schnell zu verstehen

index

index 和 all 区别为 index 类型只遍历索引树,这通常比 all 快,因为索引文件通常比数据文件小;也就是说虽然 all 和 index 都是读写表,但 index 是从索引中读取的,而 all 是从硬盘中读的;

EXPLAIN SELECT barcode FROM sku WHERE deleted=0;

Dieser Artikel hilft Ihnen, den MySQL-Ausführungsplan schnell zu verstehen

all

也就是全表扫描;

EXPLAIN SELECT * FROM sku WHERE deleted=0;

Dieser Artikel hilft Ihnen, den MySQL-Ausführungsplan schnell zu verstehen

(6)possible_keys

查询可能使用到的索引都会在这里列出来。

(7)key

查询真正使用到的索引,select_typeindex_merge时,这里可能出现两个以上的索引,其他的select_type这里只会出现一个。

(8)key_len

key_len 表示该列计算查询中使用的索引的长度。例如:SELECT * FROM table where age = 1 and name like 'xx',假设 age 是 int 类型且不可为 null;name 是 varchar(20) 类型且可以为 null,编码为 utf8。若以这两个字段为索引查询,那么 key_len 的值为 4 + 3 * 20 + 2 + 1 = 67

(5) Typ🎜🎜🎜vom Besten zum Schlechtesten: 🎜
🎜system>const > ;eq_ref>ref>ref_or_null>range>index > ;ALL🎜
🎜Zusätzlich zu all können auch andere Typen einen Index verwenden, außer index_merge, andere <code>type können nur einen Index verwenden. 🎜🎜Lassen Sie uns selbst eine Reihe von Tabellen zum Experimentieren erstellen: 🎜🎜Dieser Artikel hilft Ihnen, den MySQL-Ausführungsplan schnell zu verstehen🎜🎜 Dieser Artikel hilft Ihnen, den MySQL-Ausführungsplan schnell zu verstehen🎜rrreee

🎜system🎜

🎜Die Tabelle hat nur eine Zeile mit Datensätzen (entspricht der Systemtabelle). Dies ist ein Sonderfall von der const-Typ und erscheint normalerweise nicht. 🎜

🎜const🎜

🎜 bedeutet, dass er einmal über den Index gefunden werden kann, und const ist Wird zum Vergleichen von Primärschlüsseln oder eindeutigen Indizes verwendet. Da nur eine Zeile mit Datensätzen übereinstimmt, ist der Vorgang sehr schnell. Wenn Sie den Primärschlüssel in die Where-Liste einfügen, kann MySQL die Abfrage in eine Konstante konvertieren. png" title="166635613440181Dieser Artikel hilft Ihnen, den MySQL-Ausführungsplan schnell zu verstehen" alt="Dieser Artikel hilft Ihnen, den MySQL-Ausführungsplan schnell zu verstehen"/>🎜

🎜eq_ref🎜

🎜Einzigartiger Indexscan, für jeden Indexschlüssel, Es gibt Es gibt nur einen Datensatz in der Tabelle, der damit übereinstimmt, und er wird häufig für Primärschlüssel- oder eindeutige Indexscans verwendet. Dieser Typ erscheint normalerweise in äquivalenten Verknüpfungsabfragen mehrerer Tabellen, was bedeutet, dass jedes Ergebnis in der vorherigen Tabelle nur mit einer Zeile von übereinstimmen kann Ergebnisse in der folgenden Tabelle: Die Abfrageeffizienz ist höher. 🎜rrreee🎜Dieser Artikel hilft Ihnen, den MySQL-Ausführungsplan schnell zu verstehen🎜🎜ref🎜🎜Der nicht eindeutige Indexscan gibt alle Zeilen zurück, die mit einem einzelnen Wert übereinstimmen. Es handelt sich im Wesentlichen um einen Indexzugriff. Er gibt alle Zeilen zurück, die mit einem einzelnen Wert übereinstimmen. Zeilen finden jedoch möglicherweise mehrere übereinstimmende Zeilen, daher sollte es eine Mischung aus Suchen und Scannen sein. 🎜rrreee🎜 166635614230169Dieser Artikel hilft Ihnen, den MySQL-Ausführungsplan schnell zu verstehen" title="166635614230169Dieser Artikel hilft Ihnen, den MySQL-Ausführungsplan schnell zu verstehen" alt="Dieser Artikel hilft Ihnen, den MySQL-Ausführungsplan schnell zu verstehen"/>🎜

🎜ref_or_null🎜

🎜Sekundärindex usw. Wertvergleiche sind ebenfalls zulässig ist null . 🎜rrreee🎜Dieser Artikel hilft Ihnen, den MySQL-Ausführungsplan schnell zu verstehen🎜🎜range🎜🎜Nur Zeilen in einem bestimmten Bereich abrufen. Verwenden Sie einen Index, um Zeilen auszuwählen. Die Schlüsselspalte zeigt an, welcher Index verwendet werden soll. Er erscheint normalerweise in Ihrer Where-Anweisungsabfrage zwischen, , in usw.; dieser Bereichsindexscan ist besser als ein vollständiger Tabellenscan, da er nur an einem bestimmten Punkt im Index beginnen und an einem anderen Punkt enden muss, ohne den gesamten Index zu scannen; 🎜rrreee 🎜Dieser Artikel hilft Ihnen, den MySQL-Ausführungsplan schnell zu verstehen🎜🎜index🎜🎜index und alle Der Unterschied besteht darin, dass der Indextyp nur den Indexbaum durchläuft, was normalerweise schneller ist als alle anderen, da die Indexdatei normalerweise kleiner ist als die Datendatei; das heißt, obwohl der gesamte Index eine Lese-/Schreibtabelle ist, wird der Index aus dem Index gelesen, während alles von der Festplatte gelesen wird 🎜rrreee🎜Dieser Artikel hilft Ihnen, den MySQL-Ausführungsplan schnell zu verstehen🎜

🎜alle 🎜

🎜Das heißt, vollständiger Tabellenscan ;🎜rrreee🎜Dieser Artikel hilft Ihnen, den MySQL-Ausführungsplan schnell zu verstehen🎜

🎜(6)possible_keys🎜🎜🎜Die Indizes, die in Abfragen verwendet werden können, werden hier aufgelistet. 🎜

🎜(7)key🎜🎜🎜Fragen Sie den tatsächlich verwendeten Index ab. Wenn select_type index_merge ist, wird dies möglicherweise angezeigt Bei mehr als zwei Indizes wird hier nur einer der anderen select_type angezeigt. 🎜

🎜(8)key_len🎜🎜🎜key_len gibt die Länge des Index an, der bei der Berechnung der Abfrage verwendet wird. Beispiel: SELECT * FROM table where age = 1 and name like 'xx', vorausgesetzt, dass age vom Typ int ist und nicht null sein kann; name ist vom Typ varchar(20) und kann null sein, und die Kodierung ist utf8. Wenn diese beiden Felder als Indexabfragen verwendet werden, beträgt der Wert von key_len 4 + 3 * 20 + 2 + 1 = 67. Die spezifischen Berechnungsregeln sind in der folgenden Tabelle aufgeführt: 🎜

Werttyp Wertname Beschreibung
String CHAR(n) n Byte. Länge

V ARCHAR(n) Wenn es sich um eine UTF8-Kodierung handelt, es ist 3 n + 2 Bytes; wenn es sich um utf8mb4-Kodierung handelt, sind es 4 n + 2 Bytes.
Numerischer Typ TINYINT 1 Byte

SMALLINT 2 Bytes

MEDIUMINT 3 Bytes

INT 4 Bytes

BIGINT 8 Bytes
Zeittyp DATE 3 Bytes

TIMESTAMP . 4 Bytes

DATETIME 8 Bytes
Feldattribute NULL-Attribute belegen ein Byte. Wenn ein Feld NOT NULL ist, ist es nicht belegt.

(9)ref

Wenn es sich um eine konstante äquivalente Abfrage handelt, wird hier const angezeigt. Wenn es sich um eine Verbindungsabfrage handelt, werden im Ausführungsplan der gesteuerten Tabelle die zugehörigen Felder angezeigt Wenn die Bedingung einen Ausdruck oder eine Funktion verwendet oder die Bedingungsspalte einer internen impliziten Konvertierung unterzogen wird, wird sie möglicherweise als func angezeigt. const,如果是连接查询,被驱动表的执行计划这里会显示驱动表的关联字段,如果是条件使用了表达式或者函数,或者条件列发生了内部隐式转换,这里可能显示为func

(10)rows

这里是执行计划中估算的扫描行数,不是精确值。

(11)filtered

使用explain extended时会出现这个列,5.7之后的版本默认就有这个字段,不需要使用explain extended了。这个字段表示存储引擎返回的数据在server层过滤后,剩下多少满足查询的记录数量的比例,注意是百分比,不是具体记录数。

(12)Extra

这个列可以显示的信息非常多,有几十种,常用的有:

1、distinct:在select部分使用了distinct关键字

2、no tables used:不带from字句的查询或者From dual查询。使用not in()形式子查询或not exists()运算符的连接查询,这种叫做反连接。即,一般连接查询是先查询内表,再查询外表,反连接就是先查询外表,再查询内表。

3、using filesort:说明mysql会对数据使用一个外部的索引排序,而不是按照表内的索引顺序进行读取。mysql中无法利用索引完成的排序操作称为“文件排序”。排序时无法使用到索引时,就会出现这个。常见于order by语句中,需要尽快优化

4、using index:查询时不需要回表查询,直接通过索引就可以获取查询的数据。

5、using join buffer(block nested loop),using join buffer(batched key accss)5.6.x之后的版本优化关联查询的BNLBKA特性。主要是减少内表的循环数量以及比较顺序地扫描查询。

6、using sort_union,using_union,using intersect,using sort_intersection:

  • using intersect:表示使用and的各个索引的条件时,该信息表示是从处理结果获取交集
  • using union:表示使用or连接各个使用索引的条件时,该信息表示从处理结果获取并集
  • using sort_union和using sort_intersection:与前面两个对应的类似,只是他们是出现在用andor查询信息量大时,先查询主键,然后进行排序合并后,才能读取记录并返回。

7、using temporary:表示使用了临时表存储中间结果。临时表可以是内存临时表和磁盘临时表,执行计划中看不出来,需要查看status变量,used_tmp_tableused_tmp_disk_table才能看出来。常见于order by和分组查询group bygroup by一定要遵循所建索引的顺序与个数。需要尽快优化

8、using where:表示存储引擎返回的记录并不是所有的都满足查询条件,需要在server层进行过滤。查询条件中分为限制条件和检查条件,5.6之前,存储引擎只能根据限制条件扫描数据并返回,然后server层根据检查条件进行过滤再返回真正符合查询的数据。5.6.x之后支持ICP特性(index condition pushdown,索引下推),可以把检查条件也下推到存储引擎层,不符合检查条件和限制条件的数据,直接不读取,这样就大大减少了存储引擎扫描的记录数量。extra列显示using index condition

9、firstmatch(tb_name)5.6.x开始引入的优化子查询的新特性之一,常见于where字句含有in()类型的子查询。如果内表的数据量比较大,就可能出现这个

10、loosescan(m..n)5.6.x之后引入的优化子查询的新特性之一,在in()

(10)rows

Hier ist die geschätzte Anzahl der Scanzeilen im Ausführungsplan, kein exakter Wert.

(11) gefiltert

🎜🎜Diese Spalte wird angezeigt, wenn explain advanced verwendet wird, und die Version nach 5.7 wird angezeigt standardmäßig sein. Bei diesem Feld ist die Verwendung von explain advanced nicht erforderlich. Dieses Feld gibt den Anteil der verbleibenden Datensätze an, die die Abfrage erfüllen, nachdem die von der Speicher-Engine zurückgegebenen Daten auf der Serverebene gefiltert wurden. Beachten Sie, dass es sich um einen Prozentsatz und nicht um eine bestimmte Anzahl von Datensätzen handelt. 🎜

🎜(12) Extra🎜🎜🎜Diese Spalte kann viele Informationen anzeigen, es gibt Dutzende davon, die am häufigsten verwendeten sind: 🎜🎜🎜1, eindeutig🎜: ​​in distinct wird im Teil >select

verwendet🎜🎜🎜2 keine Tabellen verwendet🎜: Abfrage ohne from oder Von dual code>Query. Verwenden Sie die Formularunterabfrage <code>not in() oder die Join-Abfrage des Operators not exist(), die als Anti-Join bezeichnet wird. Das heißt, eine allgemeine Join-Abfrage fragt zuerst die innere Tabelle und dann die äußere Tabelle ab, während eine Anti-Join-Abfrage zuerst die äußere Tabelle und dann die innere Tabelle abfragt. 🎜🎜🎜3. Verwenden von Filesort🎜: Beschreibung mysql sortiert die Daten mithilfe eines externen Indexes, anstatt sie in der Reihenfolge des Indexes in der Tabelle zu lesen. Der Sortiervorgang, der nicht mithilfe von Indizes in mysql abgeschlossen werden kann, wird als „Dateisortierung“ bezeichnet. Dies tritt auf, wenn der Index beim Sortieren nicht verwendet werden kann. Wird häufig in order by-Anweisungen verwendet und muss so schnell wie möglich mithilfe des Index optimiert werden🎜: Es ist nicht erforderlich, bei der Abfrage zur Tabelle zurückzukehren, und die Abfragedaten können sein direkt über den Index abgerufen werden. 🎜🎜🎜5. Verwendung des Join-Puffers (blockierte verschachtelte Schleife), Verwendung des Join-Puffers (Batch-Key-Zugriff)🎜: 5.6.x und spätere Versionen optimieren BNL für verwandte Abfragen, BKA-Funktion. Der Hauptzweck besteht darin, die Anzahl der Schleifen in der internen Tabelle zu reduzieren und die Abfrage sequentiell zu scannen. 🎜🎜🎜6. using sort_union, using_union, using intersect, using sort_intersection: 🎜🎜
  • using intersect: Wenn Sie die Bedingungen jedes Index mit und angeben, geben diese Informationen an, dass dies der Fall ist verarbeitet aus Ergebniserfassungsschnittpunkt
  • unter Verwendung von Union: Gibt an, dass bei Verwendung von oder zum Verbinden von Bedingungen mithilfe von Indizes diese Informationen darauf hinweisen, dass die Union aus den Verarbeitungsergebnissen erhalten wird
  • Verwendung von sort_union und Verwendung von sort_intersection: Ähnlich wie bei den beiden vorherigen, außer dass sie bei Verwendung von and und or zum Abfragen einer großen Menge an Informationen angezeigt werden Zuerst wird der Datensatz abgefragt, dann sortiert und zusammengeführt. Erst dann kann der Datensatz gelesen und zurückgegeben werden.
🎜🎜7. Verwendung von temporär🎜: Gibt an, dass eine temporäre Tabelle zum Speichern von Zwischenergebnissen verwendet wird. Temporäre Tabellen können temporäre Speichertabellen und temporäre Festplattentabellen sein. Sie sind im Ausführungsplan nicht sichtbar. Sie müssen die Variablen status, used_tmp_table und used_tmp_disk_table überprüfen um es zu sehen. Wird häufig in sortieren nach und Gruppenabfragen gruppieren nach verwendet. group by muss der Reihenfolge und Anzahl der erstellten Indizes folgen. Muss so schnell wie möglich optimiert werden🎜🎜🎜8 mit where🎜: Zeigt an, dass nicht alle von der Speicher-Engine zurückgegebenen Datensätze die Abfragebedingungen erfüllen und auf der Server-Ebene gefiltert werden müssen. Abfragebedingungen sind in Einschränkungsbedingungen und Inspektionsbedingungen unterteilt. Vor 5.6 konnte die Speicher-Engine nur Daten scannen und sie basierend auf den Einschränkungsbedingungen zurückgeben, und dann konnte die Server-Schicht dies tun Filtern Sie die Daten und geben Sie sie basierend auf den Prüfbedingungen zurück, die tatsächlich mit der Abfrage übereinstimmen. 5.6.x unterstützt die ICP-Funktion (Indexbedingungs-Pushdown, Index-Pushdown) nach 5.6.x. Die Prüfbedingungen können auch nach unten verschoben werden Die Speicher-Engine-Schicht erfüllt die Prüfbedingungen und Einschränkungen nicht. Die Daten werden nicht direkt gelesen, was die Anzahl der von der Speicher-Engine gescannten Datensätze erheblich reduziert. In der Spalte extra wird 🎜Indexbedingung verwenden🎜🎜🎜🎜9, firstmatch(tb_name)🎜 angezeigt: eine der neuen Funktionen der optimierten Unterabfrage, die in 5.6.x eingeführt und häufig verwendet wird in Die where-Klausel enthält eine Unterabfrage vom Typ in(). Wenn die Datenmenge in der internen Tabelle relativ groß ist, kann dies auftreten🎜🎜🎜10. Loosescan(m..n)🎜: Eine der neuen Funktionen optimierter Unterabfragen, die nach 5.6.x eingeführt wurden , in In einer Unterabfrage vom Typ in() kann dies passieren, wenn die Unterabfrage doppelte Datensätze zurückgibt. 🎜🎜🎜4 Erklären Sie den Hauptfokus. Im Allgemeinen müssen wir nur auf a achten paar Spalten in den Ergebnissen: 🎜
Spaltenname Bemerkungen
Typ Dieser Verbindungstyp der Abfragetabelle. Von hier aus können Sie die ungefähre Effizienz dieser Abfrage sehen
Schlüssel Der endgültig ausgewählte Index, wenn nicht In In Bezug auf die Indizierung ist die Effizienz dieser Abfrage normalerweise sehr schlecht
key_len Die tatsächliche Länge des Index, der für die Ergebnisfilterung in dieser Abfrage verwendet wird
Zeilen Die geschätzte Anzahl der Datensätze, die gescannt werden müssen , die geschätzte Anzahl der Datensätze, die gescannt werden müssen ist größer. Kleiner ist besser
Extra Zusätzliche zusätzliche Informationen, hauptsächlich bestätigen, ob es zwei Situationen gibt: Verwenden von Dateisortierung und Temporär verwendenUsing filesortUsing temporary这两种情况

再来看下Extra列中需要注意出现的几种情况:

关键字 备注
Using filesort 将用外部排序而不是按照索引顺序排列结果,数据较少时从内存排序,否则需要在磁盘完成排序,代价非常高,需要添加合适的索引
Using temporary 需要创建一个临时表来存储结果,这通常发生在对没有索引的列进行GROUP BY时,或者ORDER BY里的列不都在索引里,需要添加合适的索引
Using index 表示MySQL使用覆盖索引避免全表扫描,不需要再到表中进行二次查找数据,这是比较好的结果之一。注意不要和type中的index类型混淆
Using where 通常是进行了全表/全索引扫描后再用WHERE子句完成结果过滤,需要添加合适的索引
Impossible WHERE Where子句判断的结果总是false而不能选择任何数据,例如where 1=0,无需过多关注
Select tables optimized away 使用某些聚合函数来访问存在索引的某个字段时,优化器会通过索引直接一次定位到所需要的数据行完成整个查询,例如MIN()MAX()
Werfen wir noch einmal einen Blick darauf. Es gibt mehrere Situationen, die in der Spalte Extra beachtet werden müssen:

🎜Schlüsselwörter🎜🎜Bemerkungen🎜🎜🎜🎜 🎜🎜Die Verwendung von Filesort🎜🎜 verwendet eine externe Sortierung, anstatt die Ergebnisse in der Indexreihenfolge zu sortieren, wenn weniger Daten vorhanden sind. Andernfalls muss die Sortierung auf der Festplatte erfolgen, was sehr kostspielig ist. 🎜Es muss ein geeigneter Index hinzugefügt werden 🎜🎜🎜🎜🎜Temporär verwenden🎜🎜Sie müssen eine temporäre Tabelle erstellen, um die Ergebnisse zu speichern. Dies geschieht normalerweise, wenn kein Index vorhanden ist, wenn die Spalten in GROUP BY ausgeführt werden ORDER BY nicht alle im Index enthalten sind, müssen Sie entsprechende Indizes hinzufügen Es ist nicht erforderlich, zweimal in der Tabelle nach Daten zu suchen. Dies ist eines der besseren Ergebnisse. Achten Sie darauf, es nicht mit dem Typ index in type zu verwechseln / Die Code>-Klausel vervollständigt die Ergebnisfilterung. 🎜Sie müssen einen geeigneten Index hinzufügen. Unmögliches WHERE. Das Ergebnis der Beurteilung der Where-Klausel ist immer falsch und es können keine Daten ausgewählt werden , wie zum Beispiel wobei 1=0, müssen Sie nicht zu viel aufpassen das erforderliche Feld auf einmal durch den Index Die Datenzeile vervollständigt die gesamte Abfrage, z. B. MIN()MAX(), was auch eines der besseren Ergebnisse ist🎜🎜🎜🎜🎜[Verwandte Empfehlung: 🎜 MySQL-Video-Tutorial🎜]🎜

Das obige ist der detaillierte Inhalt vonDieser Artikel hilft Ihnen, den MySQL-Ausführungsplan schnell zu verstehen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:juejin.cn. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen