这是我参与8月更文挑战的第17天,活动详情查看:8月更文挑战
前言
在之前我们已经使用过
explain查看过执行计划,但是没有做深入的了解,在这里统一整理一下。
EXPLAIN
使用方式
想要查看一个
SQL语句的执行计划,我们只需要在这条SQL前面,加上EXPLAIN关键字,执行就可以的得到以下执行计划结果,如下图所示。
结果解释
执行结果有很多列,每一列都有自己的含义,我们需要了解这些列,才能看懂执行计划,并作出合理的优化措施。
id
id列的编号是select的序列号,有几个select就有几个id,并且id的顺序是按select出现的顺序增长的,id为1的是驱动表
select_type
查询类型,说明查询的种类
常见的种类有以下几种:
- SIMPLE: 简单查询,查询中不包含子查询和
union- PRIMARY:复杂查询中最外层的
select- DERIVED:包含在
FROM字句中的子查询。MySQL会将结果存放在一个临时表中,也称为派生表- UNION:在
union中的第二个随后的select- UNION RESULT:从
union临时表检索结果的select- SUBQUERY:包含在
select查询条件中的子查询,如select (select * from a) from b中的select * from a注意:如非逼不得已,尽量不要使用UNION,因为UNION会做一个去重的操作,生成一个临时表,这个临时表是没有索引的,数据量大的情况下必然会查询很慢,这里指的是UNION但是使用UNION ALL是不会有去重操作的,也就不会有执行计划中UNION RESULT这一步
table
表示正在访问哪一个表
partition
说明查询作用在哪个分区表上
type
表示关联类型或访问类型,即
MySQL决定如何查找表中的行
type种类,执行效率排序(这里只解释常见类型的含义)
- system
- const:
MySQL能对查询的某部分进行优化变成一个常量,用于primary key或者unique key的所在列与常数比较时,所以表中最多只有1条与之匹配,速度非常快- eq_ref:被关联时,
primary key或者unique key的所在列被当作关联条件使用,最多只返回一条符合结果的记录,单表查询不会出现这种类型。- ref:相比于
eq_ref,被关联时不适用唯一索引,而是使用普通索引或者唯一索引的部分前缀,索引要和某个值相比较,可能会返回多个符合条件的行- fulltext
- ref_or_null:和
ref类似,可以搜索值为null的行- index_merge
- unique_subquery
- range:范围扫描,通常出现在
in()、>、<、between等操作中,使用一个索引来检索给定的一个范围,速度取决于范围的大小- index:和ALL一样,不同就是MySQL只需要扫描索引树,这通常比ALL快一些
- ALL:全表扫描,以为着MySQL需要从头到尾的去查找满足条件的行。通常情况下这里是需要添加索引优化的地方了。
possible_keys
显示查询可能使用哪些索引来查找
key
显示具体使用了哪个索引来进行查找
key_len
显示
MySQL在索引里使用的字节数,通过这个值可以算出具体使用了索引中的哪些列
rows
显示
MySQL估计要读取并检索的行数,注意这个不是结果集的行数
filtered
这一列显示的是一个百分比的值,代表
(rows * filtered / 100),这个结果将于浅表产生交互
Extra
这一列展示的是额外的信息 下面记录一些常见的信息
- distinct:一旦
MySQL找到了与行相联合匹配的行,就不在搜索了- Using index:这个发生在对表的请求列都是同一索引的部分的时候,返回的数据只使用了索引中的信息,而没有再去访问表中行的记录,是性能高的表现。
- Using where:条件查询的时候,符合就留下,不符合就丢掉
- Using temporary:需要建立临时表来处理查询的时候。出现这种情况一般是要进行优化的。
- Using filesort:采用文件扫描对结果进行计算排序,效率很差。