MySQL EXPLAIN 使用

MySQL EXPLAIN

explain 能解释 mysql 如何处理SQL语句,表的加载顺序,表是如何连接,以及索引使用情况。是SQL优化的重要工具。建议在做项目时使用 explain 对所有的sql 命令进行分析,然后决定是否需要进一步优化。

执行命令示例 :

EXPLAIN SELECT * FROM students WHERE class_id > 1;

返回结果

id  select_type  tabld     partitions   type   possible_ky   key       key_len  ref  rows  filtered   extra
1	SIMPLE	     students               range	class_id	class_id	5		      3	   100.00	  Using index condition

返回值解释

id

id相同,执行顺序从上之下
id不同,执行顺序从大到小
id相同不同,同时存在,遵守1、2规则

select_type

查询中每个select的查询类型,如下:

SIMPLE:简单select,不使用union和子查询
PRIMARY:查询中包含任何复杂的子部分,最外层的select被标记为PRIMARY
UNION:union中第二个后面的select语句
DEPENDENT UNION:一般是子查询中的第二个select语句(取决于外查询,mysql内部也有些优化)
UNION RESULT:union的结果
SUBQUERY:子查询中的第一个select
DEPENDENT SUBQUERY:子查询中第一个select,取决于外查询(在mysql中会有些优化,有些dependent会直接优化成simple)
DERIVED:派生表的select(from子句的子查询)

type

type 这个字段是我们优化要重点关注的字段,这个字段直接反映我们SQL的性能是否高效。这个字段值较多,这里我只重点关注我们开发中经常用到的几个字段:system,const,eq_ref,ref,range,index,all;
性能由好到差依次为:

system>const>eq_ref>ref>range>index>all
system:表只有一行记录,这个是const的特例,一般不会出现,可以忽略。
const:表示通过索引一次就找到了,const用于比较primary key或者unique索引。因为只匹配一行数据,所以很快。
eq_ref:唯一性索引扫描,表中只有一条记录与之匹配。一般是两表关联,关联条件中的字段是主键或唯一索引。
ref:非唯一行索引扫描,返回匹配某个单独值的所有行。
range:检索给定范围的行,一般条件查询中出现了>、<、in、between等查询。
index:遍历索引树。通常比ALL快,因为索引文件通常比数据文件小。all和index都是读全表,但index是从索引中检索的,而all是从硬盘中检索的。
all:遍历全表以找到匹配的行

possible_keys

显示可能应用在这张表中的索引,但不一定被查询实际使用key实际使用的索引。

key_len

表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度。一般来说,索引长度越长表示精度越高,效率偏低;长度越短,效率高,但精度就偏低。并不是真正使用索引的长度,是个预估值。ref表示哪一列被使用了,常数表示这一列等于某个常数。

rows

大致找到所需记录需要读取的行数。

filter

表示选取的行和读取的行的百分比,100表示选取了100%,80表示读取了80%。

extra一些重要的额外信息

Using filesort:使用外部的索引排序,而不是按照表内的索引顺序进行读取。(一般需要优化)
Using temporary:使用了临时表保存中间结果。常见于排序order by和分组查询group by(最好优化)
Using index:表示select语句中使用了覆盖索引,直接冲索引中取值,而不需要回行(从磁盘中取数据)
Using where:使用了where过滤
Using index condition:5.6之后新增的,表示查询的列有非索引的列,先判断索引的条件,以减少磁盘的IO
Using join buffer:使用了连接缓存
impossible where:where子句的值总是false

通过 explain 命令可以清楚的了解 MySQL 语句运行的过程,我们可以通过合理地设置索引、优化查询语句等手段来保证整个项目 SQL 命令的高效性。