MySQL explain详解

本文参考 MySQL官方文档对explain的解释

语法

explain [extended|partitions] SQL_Statement

在较早的 MySQL 版本(5.7之前)中,分区和扩展信息是使用EXPLAIN PARTITIONSEXPLAIN EXTENDED生成的。仍然可以识别这些语法的向后兼容性,但是默认情况下现在启用分区和扩展输出,因此PARTITIONSEXTENDED关键字是多余的并且已弃用。使用它们会导致警告,并且在将来的 MySQL 版本中会将它们从EXPLAIN语法中删除。

您不能在同一EXPLAIN语句中一起使用已弃用的PARTITIONSEXTENDED关键字。此外,这两个关键字都不能与FORMAT选项一起使用。

EXPLAIN 输出列

EXPLAIN的每个输出行均提供有关一个 table 的信息,列名显示在 table 的第一列中;第二列提供使用FORMAT=JSON时在输出中显示的等效属性名称。本文后面只分析第一列的情况,更多详细信息参考mysql官方文档。

ColumnJSON NameMeaning
idselect_idSELECT标识符
select_typeNoneSELECT类型
tabletable_name输出行 table
partitionspartitions匹配的分区
typeaccess_type联接类型
possible_keyspossible_keys可能的索引选择
keykey实际选择的索引
key_lenkey_length所选键的长度
refref与索引比较的列
rowsrows估计要检查的行
filteredfiltered按 table 条件过滤的行百分比
ExtraNone

下面对这些字段进行详细解释

id

SELECT识别符,这是SELECT的查询序列号。如果该行引用其他行的并集结果,则值可以为NULL。在这种情况下,table列显示类似于<unionM,N>的值,以指示该行引用具有idM N 的行的并集。

不同级别的id ,高级别先执行
同一级别的id 从上到下

select_type

就是select类型,可以有以下几种

select_type含义
SIMPLE简单SELECT,不使用UNION或子查询
PRIMARY子查询中最外层查询,查询中若包含任何复杂的子部分,最外层的select被标记为PRIMARY
UNIONUNION中的第二个或后面的SELECT语句
DEPENDENT UNIONUNION中的第二个或后面的SELECT语句,依赖于外面的查询
UNION RESULTUNION的结果
SUBQUERY子查询中的第一个SELECT
DEPENDENT SUBQUERY子查询中的第一个SELECT,依赖于外部查询
DERIVED派生表的SELECT(FROM子句的子查询)
MATERIALIZED物化子查询
UNCACHEABLE SUBQUERY一个子查询的结果不能被缓存,必须重新评估外链接的第一行
UNCACHEABLE UNION属于不能被缓存的UNION中的第二个或后面的SELECT语句

table

输出行所引用的 table 的名称。有时也可以是简称(查询中命名的某个表的别名或者某一步子查询结果的别名)

partitions

查询将从中匹配记录的分区。对于非分区 table,该值为NULL

type

联接类型(体现性能),从上到下,性能由低到高

type含义
ALL全表扫描
index全索引扫描
range范围扫描
index_subquery子查询的列是普通索引
unique_subquery子查询的列是唯一索引
index_mergeor查询会使用到的类型
ref_or_null和ref类似,使用普通索引查询,但是要查询null值
fulltext使用全文索引进行查询
ref使用普通索引进行查询
eq_ref当连接使用索引的所有部分且索引为PRIMARY KEYUNIQUE NOT NULL索引时使用
const最多只有一条返回记录,比如主键查询
system表只有一行记录(等于系统表),这是const类型的特例

possible_keys

表示MySQL 可以选择从中查找 table 中各行的索引。请注意,此列完全独立于EXPLAIN的输出中显示的 tableSequences。这意味着possible_keys中的某些键实际上可能无法用于生成的 tableSequences

如果此列为NULL(或在 JSON 格式的输出中未定义),则没有相关的索引。在这种情况下,您可以通过检查WHERE子句以检查其是否引用某些适合索引的列来提高查询性能。如果是这样,请创建一个适当的索引,然后再次使用EXPLAIN检查查询。

key

MySQL 实际决定使用的索引。

key_len

MySQL 实际决定使用的索引的长度。

ref

显示将哪些列或常量与key列中命名的索引进行比较,以从 table 中选择行

rows

表示 MySQL 预估执行查询必须检查的行数。

filtered

表示将被 table 条件过滤的 table 行的估计百分比。

最大值为 100,表示没有行过滤发生。值从 100 减小 table 示过滤量增加。

Extra

本列包含有关 MySQL 如何解析查询的其他信息。

以下很多内容这里只是搬运,实际没见过。常见的已加粗

具体值解释

  • Child of 'table' pushed join@1

该 table 在可以下推到 NDB 内核的 Connecting 被称为table的子级。启用下推联接时,仅适用于 NDB 群集。有关更多信息和示例,请参见ndb_join_pushdown服务器系统变量的描述。

  • const row not found

对于诸如SELECT ... FROM tbl_name的查询,该表为空。

  • Deleting all rows(JSON 属性:message)

对于DELETE,某些存储引擎(例如MyISAM)支持处理程序方法,该方法以一种简单而快速的方式删除所有 table 行。如果引擎使用此优化,则会显示此Extra值。

  • Distinct

MySQL正在寻找不同的值,因此在找到第一个匹配的行后,它将停止为当前行组合搜索更多行。

  • FirstMatch(tbl_name)

半连接 FirstMatch 连接快捷方式用于 tbl_name

  • Full scan on NULL key

当优化器无法使用索引查找访问方法时,这会作为子查询优化的后备策略发生。

  • Impossible HAVING

HAVING子句始终为 false,无法选择任何行。

  • Impossible WHERE

WHERE子句始终为 false,无法选择任何行。

  • Impossible WHERE noticed after reading const tables

MySQL 已读取所有const(和system)table,并注意WHERE子句始终为 false。

  • LooseScan(m..n)

使用半连接的 LooseScan 策略。 * m n *是关键 Component 号。

  • No matching min/max row

没有行满足诸如SELECT MIN(...) FROM ... WHERE condition之类的查询的条件。

  • no matching row in const table

对于具有联接的查询,存在一个空 table 或没有满足唯一索引条件的行的 table。

  • No matching rows after partition pruning

对于DELETEUPDATE,优化器在分区修剪后找不到要删除或更新的内容。 SELECT语句的含义与Impossible WHERE相似。

  • No tables used

该查询没有FROM子句,或者没有FROM DUAL子句。

对于INSERTREPLACE语句,如果没有SELECT部分,则EXPLAIN将显示此值。

  • Not exists

MySQL能够对查询进行LEFT JOIN优化,并且在找到与LEFT JOIN条件匹配的一行后,不检查该 table 中的更多行以进行前一行的组合。

  • Plan isn't ready yet

当优化程序尚未完成为在命名 Connecting 执行的语句的执行计划的创建时,此值出现在连接说明处。如果执行计划输出包含多行,则它们中的任何一个或全部都可以具有Extra值,这取决于优化程序确定完整执行计划的进度。

  • Range checked for each record (index map: N)

MySQL 找不到理想的索引来使用,但是发现在知道先前表中的列值之后可能会使用某些索引。对于上表中的每个行组合,MySQL 检查是否可以使用rangeindex_merge访问方法来检索行。这不是很快,但是比根本没有索引的连接要快。

  • Scanned N databases

这表示在处理INFORMATION_SCHEMA表的查询时服务器执行的目录扫描次数,

  • Select tables optimized away

优化器确定最多应返回一行,以及要生成该行,必须读取确定的一组行。当在优化阶段可以读取要读取的行时(例如,通过读取索引行),则在查询执行期间无需读取任何表。

  • Skip_open_tableOpen_frm_onlyOpen_full_table

这些值 table 示适用于INFORMATION_SCHEMAtable 查询的文件打开优化

Skip_open_table:不需要打开 table 文件。通过扫描数据库目录,该信息已在查询中可用。
Open_frm_only:仅需要打开 table 的.frm文件。
Open_full_table:未优化的信息查找。必须打开.frm.MYD.MYI文件。

  • Start temporaryEnd temporary

这表明临时 table 用于半联接重复淘汰策略。

  • unique row not found

对于诸如SELECT ... FROM tbl_name的查询,没有任何行满足 table 上UNIQUE索引或PRIMARY KEY的条件。

  • Using filesort

MySQL 必须额外进行一遍排序,以找出如何按排序Sequences检索行。排序是通过根据联接类型遍历所有行并存储与WHERE子句匹配的所有行的排序键和指向该行的指针来完成的。然后对键进行排序,并按排序 Sequences 检索行

  • Using index

仅使用索引树中的信息从表中检索列信息,而不必进行其他查找以读取实际行。当查询仅使用属于单个索引的列时,可以使用此策略。

对于具有用户定义的聚集索引的InnoDB表,即使Extra列中不存在Using index,也可以使用该索引。如果typeindex且key是PRIMARY就是这种情况。

  • Using index condition

通过访问索引Tuples并首先对其进行测试以确定是否读取完整的表行来读取表。以此方式,除非必要,否则索引信息用于推迟(“下推”)读取整个表所有行。

  • Using index for group-by

Using indextable 访问方法类似,Using index for group-bytable 示 MySQL 找到了一个索引,该索引可用于检索GROUP BYDISTINCT查询的所有列,而无需对实际 table 进行任何额外的磁盘访问。此外,以最有效的方式使用索引,因此对于每个组,仅读取少数索引条目。

  • Using join buffer (Block Nested Loop)Using join buffer (Batched Key Access)

来自较早联接的 table 被部分读取到联接缓冲区中,然后从缓冲区中使用它们的行来执行与当前 table 的联接。 (Block Nested Loop)table 示使用块嵌套循环算法,(Batched Key Access)table 示使用批处理密钥访问算法。也就是说,对EXPLAIN输出的前一行中的 table 中的键进行缓冲,并从出现Using join buffer的行所代 table 的 table 中批量提取匹配的行。

  • Using MRR

使用多范围读取优化策略读取 table。

  • Using sort_union(...)Using union(...)Using intersect(...)

这些指示了特定算法,该算法显示了如何针对index_merge连接类型合并索引扫描。

  • Using temporary

为了解决该查询,MySQL 需要创建一个临时表来保存结果。如果查询包含GROUP BYORDER BY子句以不同的方式列出列,通常会发生这种情况。

  • Using where

WHERE子句用于限制要与下一张表匹配或发送到客户端的行。除非您专门打算从表中获取或检查所有行,否则如果Extra的值不是Using where且表连接类型为ALLindex,则查询中可能会出错。

  • Using where with pushed condition

此项仅适用于NDB表格。这意味着NDB Cluster正在使用条件下推优化来提高在非索引列和常量之间进行直接比较的效率。在这种情况下,条件被“压入”群集的数据节点,并同时在所有数据节点上进行评估。这样就无需通过网络发送不匹配的行,并且在可以但不使用条件下推的情况下,可以将此类查询的速度提高 5 到 10 倍。

  • Zero limit

该查询具有LIMIT 0子句,无法选择任何行。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

pzzhao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值