explain详解

1、id

表示查询中执⾏select⼦句或者操作表的顺序:

id相同,执行顺序由上至下

explain select * from finance t1 join tb_user t2 on
t1.create_id=t2.id;

explain详解
如图所示,先查询了t2表,后查询的t1表

id不同,如果是⼦查询,id的序号会递增,id值越⼤优先级越⾼,越先被执⾏

explain select * from finance t1 where t1.create_id not in
(select id from tb_user where name='⼩明');

explain详解
先执行了内层tb_user,后执行的外层

id相同和不同的,同时存在:相同的可以认为是⼀组,从上往下顺序执⾏,在所有组中,id值越⼤,优先级越⾼,越先执⾏

explain select * from finance t1 join tb_user t2 on
t1.create_id=t2.id and t1.create_id not in(select id from
tb_user where name='⼩明');

explain详解
先执行tb_user,然后执行t2,再执行t1

2、select_type

主要⽤来分辨查询的类型,是普通查询还是联合查询还是⼦查询

  1. SIMPLE:简单的查询,不包含⼦查询和union
  2. PRIMARY: 查询中若包含任何复杂的⼦查询,最外层查询则被标记为Primary
  3. UNION: 若第⼆个select出现在union之后,则被标记为union
  4. UNION RESULT: 从union表获取结果的select
  5. SUBQUERY: 在select或者where列表中包含⼦查询
  6. DERIVED: from⼦句中出现的⼦查询,也叫做派⽣类

3、table

对应⾏正在访问哪⼀个表,表名或者别名,可能是临时表或者union合并结果集

1、如果是具体的表名,则表明从实际的物理表中获取数据,当然也可以是
表的别名
2、表名是derivedN的形式,表示使⽤了id为N的查询产⽣的衍⽣表
3、当有union result的时候,表名是union n1,n2等的形式,n1,n2表示参
与union的id

4、type

type显示的是访问类型,访问类型表示我是以何种⽅方式去访问我们的数据,效率从最好到最坏依次是:system > const > eq_ref > ref > range > index > ALL

  1. system:表只有一行记录(等于系统表);意思是表里只有一行数据
  2. const:表示通过索引一次就找到了,常用于primaryKey或者unique key,因为只匹配一行,所以很快
  3. eq_ref:唯一性索引扫描:意思是两个表联合查询时,使用了主键或者unique key,并且联合查询匹配出来的结果只有一行
  4. ref:非唯一性索引扫描:意思是两个表联合查询时,联合查询匹配出来的结果有多行
  5. range:使用索引进行范围扫描:一般在where条件后使用between、>、<、in等操作
  6. index:index与all的区别是index只遍历索引树,不用回表查询磁盘,通过索引就能覆盖到要查询的列
  7. all:全表扫描

关于eq_ref与ref的区别详见这里

5、possible_keys,key

可能用到的索引和实际用到的索引

6、ken_length

表示索引中使⽤的字节数,可通过该列列计算查询中使用的索引的长度,在不损失精确性的情况下,长度越短越好 。key_len显示的值为索引字段的最大可能⻓度,并⾮实际使⽤长度,即key_len是根据表定义计算而得,不是通过表内检索出的

7、ref

显示索引的那⼀一列列被使⽤了,如果可能的话,最好是一个常数。哪些列或常量被用于查找索引列上的值。

8、rows

扫描的行数,用的越少越好。

9、extra

Using temporary(性能极差):

使⽤了临时表保存中间结果,MySQL在对查询结果排序时使用临时表。查询
完成之后把临时表删除,常⻅于排序order by和分组查询group by

可能产生临时表的场景:

  1. 表包含TEXT或者BLOB列;
  2. GROUP BY 或者 DISTINCT 子句中包含长度大于512字节的列;
  3. 使用UNION或者UNION ALL时,SELECT子句中包含大于512字节的列。

如何规避临时表:

  1. 对group by和order by的列进行优化,添加索引;
  2. 将较大的TEXT或者BLOB列拆分成多个较小的列;
  3. 对大量的group by和order by语句做拆分;
  4. 优化业务逻辑。

Using filesort(性能较差)

说明mysql会对数据使⽤一个外部的索引排序,⽽不是按照表内的索引顺序进行读取。会消耗额外的位置,MySQL中⽆法利利用索引完成的排序操作称为“⽂件排序”

也就是说。查询中排序的字段,排序字段若通过索引访问将大大提升排序速度
比如t1表中有联合索引idx(a,b,c),如果select a from t1 where a='1' order by c,则此时会使用Using filesort;如果将sql改为select a from t1 where a='1' order by b,c,则不会产生文件排序;因为联合索引的排序规则就是a,b,c,如果排序的字段也是按索引的规则排序则就不会产生文件排序

Using index(性能尚可)
表示相应的select操作中使⽤用了了覆盖索引(Covering Index),避免访问了表的数据⾏,效率不不错。如果同时出现using where,表明索引被用来执⾏索引键值的查找;如果没有同时出现using where,表明索引⽤来读取数据而非执行查找动作

using where
表明使用了where过滤

Using join buffer
使用连接缓存

impossible where
where⼦句的值 总是false ,不能用来获取任何数据

distinct
优化distinct操作,在找到第⼀匹配的元组后即停止找同样值的动作,在select部分使用了distinc关键字

using union
表示使用or连接各个使⽤用索引的条件时,该信息表示从处理结果获取并集

上一篇:【干货,被腾讯辞退的高级Java工程师现在怎么了


下一篇:MongoDB实战篇(七):使用索引