EXPLAIN

4/21/2022 Mysql

摘要

Mysql Version:5.7.36

# 一:前言

EXPLAIN——分析sql语句执行效率是否高效,有没有使用到索引之类的;主要就是看懂它的结果,然后判断sql需要优化。

Mysql 5.6 之前的版本只能对 select 语句进行 explain,之后的版本可以对其他命令。

# 三:结果列

列名 说明
id 执行编号,表示sql语句中select的执行顺序,有几个select就有几个id,按照select出现的顺序呈现结果
select_type 显示本行是简单或复杂select。如果查询有任何复杂的子查询,则最外层标记为PRIMARY(DERIVED、UNION、UNION RESUlT)
table explain 访问的表是哪一个
type 表关联类型或访问类型,重要的一列,是判断查询是否高效的一句:也就是Mysql决定如何查找表中的行就看这个列
possible_keys 揭示哪一些索引可能有利于高效的查找
key 显示Mysql采用哪个索引来查找
key_len 显示Mysql在索引里使用的字节数
ref 显示了之前的表在key列记录的索引中查找值所用的列或常量
rows 为了找到所需的行而需要读取的行数,估算值,不精确。通过把所有rows列值相乘,可粗略估算整个查询会检查的行数
Extra 额外信息,如using index、filesort等

# 3.1 id 列

有几种情况:

  • id 相同,执行顺序由上而下
  • id 不同,序号会递增。值越大优先级越高,就越先执行

# 3.2 select_type

加粗的都是常见的:

  1. simple:简单查询。查询不包含子查询和 union,比如上面简介中演示的语句

  2. primary:跟上面相反,如果查询包含子查询和 union,就会被标记为 primary

  3. subquery:见名知义,包含在 select 中的子查询(不在 from 子句中

  4. derived:在 from 子句中子查询,MySQL 会将结果存放在一个临时表中,也称为派生表(derived 的英文含义)

  5. union:表示此查询是 UNION 中的第二个或随后的查询

  6. union result:从 union 临时表检索结果的 select

  7. dependent union:此查询是 UNION 中的第二个或随后的查询,其次取决于外面的查询

  8. uncacheable union:此查询是 UNION 中的第二个或随后的查询,同时意味着 select 中的某些特性阻止结果被缓存于一个 Item_cache 中

  9. dependent subquery:子查询中的 第一个 select,同时取决于外面的查询

  10. uncacheable subquery:子查询中的 第一个 select,同时意味着 select 中的某些特性阻止结果被缓存于一个 Item_cache 中

# 3.3 table

  • 当 from 子句中有子查询时,table 列是 <derivenN> 格式,表示当前查询依赖 id=N 的查询,于是先执行 id=N 的查询

  • 当有 union 时,UNION RESULT 的 table 列的值为 <union1,2>,1 和 2 表示参与 union 的 select 行 id

# 3.4 type

结果有很多,性能从最优到最差为:system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL

常见的几个:

  1. ALL:全表扫描,性能极差。敲黑板哈,这种类型是不应该出现的,一定还可以加索引优化。

  2. index:全索引扫描,跟 ALL 差不多,不同的是 index 是扫描整棵索引树,比 ALL 要快些。

  3. range:范围扫描,通常出现在 in (), between ,> ,<, >= 等操作中。使用一个索引来检索给定范围的行。

  4. ref:索引查找,不使用唯一索引,使用普通索引或者唯一性索引的部分前缀,索引要和某个值相比较,可能会找到多个符合条件的行。

  5. eq_ref:最多只返回一条符合条件的记录。在使用唯一性索引或主键查找时会出现该值,非常高效。

  6. const、system:该表至多有一个匹配行,在查询开始时读取,或者该表是系统表,只有一行匹配。其中 const 用于在和 primary key 或 unique 索引中有固定值比较的情形。

  7. null:在执行阶段用不着再访问表或索引。

# 3.5 possible_keys

表示 MySQL 执行查询可能会使用那些索引来查找,如果为 null,可考虑在该列加个索引

# 3.6 key

表示 MySQL 执行查询实际使用那些索引来查找,如果为 null,则证明没有使用索引。如果想强制使用或者忽略索引可以在查询语句加 force index(想要强制使用的索引名)或者 ignore index(想要忽略的索引名)

如果 possible_keys 有列,而 key 显示 null 的情况,可能是因为表数据不多,加索引作用也不大

# 3.7 key_len

在索引里使用的字节数,当 key 列的值为 NULL 时,则该列也是 NULL

索引的最大长度是 768 字节,字符串过长时,MySQL 会将前半部分提出来做索引,这点大家需要注意。(不过一般也不会在这么长的字段上建索引)

# 3.8 ref

那些字段或者常量被用来和 key 列记录的索引配合查找值,常见的有:const(常量),func,NULL,字段名(例:film.id)

# 3.9 rows

mysql 估计要读取并检测的行数,注意这个不是结果集里的行数。(只是个预测的数量)

# 3.10 Extra

额外信息,也非常重要

  1. Using index:使用覆盖索引,表示查询索引就可查到所需数据,不用回表,说明性能不错。

  2. Using where:在存储引擎检索行后再进行过滤,就是先读取整行数据,再按 where 条件进行取舍。

  3. Using temporary:mysql 需要创建一张临时表来处理查询,一般是因为查询语句中有排序、分组、和多表 join 的情况,一般是要进行优化的。

  4. Using filesort:对结果使用一个外部索引排序,而不是按索引次序从表里读取行,一般有出现该值,都建议优化去掉,因为这样的查询 CPU 资源消耗大。

https://segmentfault.com/a/1190000023565685 https://segmentfault.com/a/1190000008131735 https://learnku.com/articles/38719 https://blog.csdn.net/u014745069/article/details/104173763 https://www.itmuch.com/mysql/explain/ https://www.jianshu.com/p/ea3fc71fdc45 https://xlk3099.github.io/post/understand_explain_in_mysql/ https://www.cnblogs.com/xuanzhi201111/p/4175635.html

# 四:参考文献

最后更新: 4/22/2022, 4:10:07 PM