EXPLAIN 执行计划

330 阅读5分钟


官网释义:dev.mysql.com/doc/refman/…

explan sql 查询执行计划

EXPLAIN SELECT * FROM employees WHERE name = 'LiLei' AND age = 22 AND position ='manager';


*id

id列的编号是 select 的序列号,有几个 select 就有几个id,并且id的顺序是按 select 出现的顺序增长的。

id列越大执行优先级越高,id相同则从上往下执行,id为NULL最后执行。


select_type

表示查询中每个select子句的类型(简单 OR复杂)

  • (1) SIMPLE(简单SELECT,不使用UNION或子查询等)[就简简单单的一个select查询]
  • (2) PRIMARY [复杂查询中最外层的 select ]
  • (3) UNION(UNION中的第二个或后面的SELECT语句)
  • (4) DEPENDENT UNION(UNION中的第二个或后面的SELECT语句,取决于外面的查询)
  • (5) UNION RESULT(UNION的结果)
  • (6) SUBQUERY(子查询中的第一个SELECT) [包含在 select 中的子查询(不在 from 子句中)]
  • (7) DEPENDENT SUBQUERY(子查询中的第一个SELECT,取决于外面的查询)
  • (8) DERIVED(派生表的SELECT, FROM子句的子查询)[就是在from后面又跟了一个select子句]
  • (9) UNCACHEABLE SUBQUERY(一个子查询的结果不能被缓存,必须重新评估外链接的第一行)

table

这一列表示 explain 的一行正在访问哪个表。

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

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


*type

这一列表示关联类型或访问类型,即MySQL决定如何查找表中的行,查找数据行记录的大概范围。

常用的类型有: ALL, index, range, ref, eq_ref, const, system, NULL(从左到右,性能从差到好)

  • ALL:Full Table Scan, MySQL将遍历全表以找到匹配的行
  • index: Full Index Scan,index与ALL区别为index类型只遍历索引树
  • range:只检索给定范围的行,使用一个索引来选择行
  • ref: 表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值 。普通索引、组合索引中的前缀索引
  • eq_ref: 类似ref,区别就在使用的索引是唯一索引,对于每个索引键值,表中只有一条记录匹配,简单来说,就是多表连接中使用primary key或者 unique key作为关联条件。主键索引、唯一索引
  • const、system: 当MySQL对查询某部分进行优化,并转换为一个常量时,使用这些类型访问。如将主键置于where列表中,MySQL就能将该查询转换为一个常量,system是const类型的特例,当查询的表只有一行的情况下,使用system。
  • NULL: MySQL在优化过程中分解语句,执行时甚至不用访问表或索引,例如从一个索引列里选取最小值可以通过单独索引查找完成。

[优化级别建议:一般来说,得保证查询达到range级别,最好达到ref ]


possible_keys

指出MySQL能使用哪个索引在表中找到记录,查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询使用

该列完全独立于EXPLAIN输出所示的表的次序。这意味着在possible_keys中的某些键实际上不能按生成的表次序使用。

如果该列是NULL,则没有相关的索引。在这种情况下,可以通过检查WHERE子句看是否它引用某些列或适合索引的列来提高你的查询性能。如果是这样,创造一个适当的索引并且再次用EXPLAIN检查查询

mysql 在优化器阶段可能会放弃走索引,而走全表扫描,这个时候 possible_keys 是有值的,但是 type 显示的是 All。这个和 sql cost 花费时间预估有关,mysql判断走不走索引。


*Extra

1)Using index

使用覆盖索引 覆盖索引定义:mysql执行计划explain结果里的key有使用索引,如果select后面查询的字段都可以从这个索引的树中 获取,这种情况一般可以说是用到了覆盖索引,extra里一般都有using index;覆盖索引一般针对的是辅助索引,整个 查询结果只通过辅助索引就能拿到结果,不需要通过辅助索引树找到主键,再通过主键去主键索引树里获取其它字段值

2)Using where

使用 where 语句来处理结果,并且查询的列未被索引覆盖 。

Using where; Using index同时出现,表示可通过覆盖索引获取全部信息

3)Using index condition

查询的列不完全被索引覆盖,where条件中是一个前导列的范围。查询的列,并不是所有的列都在覆盖索引中。[先走覆盖索引查询结果,再全部扫描查找其余列]

4)Using temporary

mysql需要创建一张临时表来处理查询。出现这种情况一般是要进行优化的,首先是想到用索 引来优化。

5)Using filesort

将用外部排序而不是索引排序,数据较小时从内存排序,否则需要在磁盘完成排序。这种情况下一 般也是要考虑使用索引来优化的。

6)Select tables optimized away

使用某些聚合函数(比如 max、min)来访问存在索引的某个字段是

7)Impossible WHERE

该WHERE子句始终为 false,不能选择任何行

explain总结

我们使用explain的时候最重要的几个信息分别是:

  • type 是不是达到了最低要求
  • key 是不是符合预期的索引
  • Extra 中的覆盖索引,文件排序等信息一定要看看