参考:https://www.jianshu.com/p/b5c01bd4a306,https://www.cnblogs.com/AbnerLc/p/11923460.html
通过explain关键字可以查看select语句的具体执行计划,是否和我们预期的一样。
explain只对select语句有效。
执行explain返回的字段含义:
1,id,有几个select就有几个id,id越大的select越先执行,大小一样的时候,按从上到下顺序执行,为null的时候最后执行。这里的执行是指的select的执行,并不是where条件的先后顺序,我们将select * from ttt where id = xxx 的执行顺序理解为两步,先执行where条件,查询到符合条件的记录,然后执行select,返回我们需要的字段数据
例如:
SELECT *,(select id from bbbb where idno = a.idno) FROM aaaa a WHERE 1 = 1 AND a.phone = '11111111120' and a.name = (select name from tttt where idno = '1111')
这里是先执行 select name from tttt where idno = '1111',然后执行 WHERE 1 = 1 AND a.phone = '11111111120' and a.name = (select name from tttt where idno = '1111')查询到符合条件的结果集,然后执行 select id from bbbb where idno = a.idno,最后才执行最外层select
2,select_type 表示查询类型,通常有:
simple:表示不需要union操作或者不包含子查询的简单查询。
primary:表示最外层查询。
union:union操作中第二个及之后的查询。
dependent union:union操作中第二个及之后的查询,并且该查询依赖于外部查询。
subquery:子查询中的第一个查询。
dependent subquery:子查询中的第一个查询,并且该查询依赖于外部查询。
derived:派生表查询,既from字句中的子查询。
materialized:物化查询。
uncacheable subquery:无法被缓存的子查询,对外部查询的每一行都需要重新进行查询。
uncacheable union:union操作中第二个及之后的查询,并且该查询属于uncacheable subquery。
3,table 表名或者表的别名。
4,partitions 分区信息,非分区表为null。
5,type 访问类型,表示找到所查询数据的方法,也是本文重点介绍的属性。该属性的常见值如下,性能从好到差:
NULL:无需访问表或者索引,比如获取一个索引列的最大值或最小值。
system/const:当查询最多匹配一行时,常出现于where条件是=的情况。system是const的一种特殊情况,既表本身只有一行数据的情况。
eq_ref:多表关联查询时,根据唯一非空索引进行查询的情况。
ref:多表查询时,根据非唯一非空索引进行查询的情况。
range:在一个索引上进行范围查找。
index:遍历索引树查询,通常发生在查询结果只包含索引字段时。
ALL:全表扫描,没有任何索引可以使用时。这是最差的情况,应该避免。
6,possible_keys 表示mysql此次查询中可能使用的索引。
7,key 表示mysql实际在此次查询中使用的索引。
8,key_len 表示mysql使用的索引的长度。该值越小越好。
9,ref 表示连接查询的连接条件。
10,rows 表示mysql估计此次查询所需读取的行数。该值越小越好。
11,extra 表示mysql解决查询的其他信息,有几十种不同的值,该信息也是我们优化sql可以专注的一个值
-
Using where 说明,SQL使用了where条件过滤数据。
需要注意的是:
(1)返回所有记录的SQL,不使用where条件过滤数据,大概率不符合预期,对于这类SQL往往需要进行优化;
(2)使用了where条件的SQL,并不代表不需要优化,往往需要配合explain结果中的type(连接类型)来综合判断;
Using index 说明,SQL所需要返回的所有列数据均在一棵索引树上,而无需访问实际的行记录
Using index condition 说明,确实命中了索引,但不是所有的列数据都在索引树上,还需要访问实际的行记录。
Using filesort 说明,得到所需结果集,需要对所有记录进行文件排序。这类SQL语句性能极差,需要进行优化。典型的,在一个没有建立索引的列上进行了order by,就会触发filesort,常见的优化方案是,在order by的列上添加索引,避免每次查询都全量排序。
Using temporary 说明,需要建立临时表(temporary table)来暂存中间结果。这类SQL语句性能较低,往往也需要进行优化。典型的,group by和order by同时存在,且作用于不同的字段时,就会建立临时表,以便计算出最终的结果集。
Using join buffer (Block Nested Loop) 说明,需要进行嵌套循环计算。这类SQL语句性能往往也较低,需要进行优化。典型的,两个关联表join,关联字段均未建立索引,就会出现这种情况。常见的优化方案是,在关联字段上添加索引,避免每次嵌套循环计算。