MySQL--解读执行计划

作为一名业务系统的开发人员,在企业日常开发工作中,天天相伴最多的是java代码和Sql语句。Sql的执行计划能很好的帮忙开发人员定位SQL的性能问题,预防慢SQL影响生产服务器。每个数据库的执行计划查看和呈现都不太一样,然而MySql应该说是当下流行的数据库,需要了解一下。

调用执行计划


EXPLAN 关键字:EXPLAN SELECT * FROM TABLE …

EXPLAIN SELECT
	u.*, r.*
FROM
	t_user u
LEFT JOIN t_role_user ru ON u.user_no = ru.user_no
LEFT JOIN t_role_resource rr ON ru.role_id = rr.role_id
LEFT JOIN t_resource r ON rr.resouce_id = r.id
WHERE
	u.USER_NO = '88888888';

执行计划结果
在这里插入图片描述

执行计划字段


在这里插入图片描述

id


含义:包含一组数字,表示查询中执行select子句或操作表的顺序
  • id相同:可以认为是一组,执行顺序由上至下。
  • id不同:如果是子查询,id的序号会递增,id值越大优先级越高,越先被执行
  • id为null时表示一个结果集,不需要使用它查询,常出现在包含union等查询语句中
    在这里插入图片描述

select_type


含义:表示查询中每个select子句的类型(简单 OR复杂)
常见类型:
  • SIMPLE:查询中不包含任何子查询或union等查询
  • PRIMARY:查询中若包含任何复杂的子部分,最外层查询则为PRIMARY
  • SUBQUERY:在SELECT或WHERE列表中包含了子查询
  • DEPENDENT SUBQUERY:相关子查询,子查询的查询方式依赖于外面的查询结果
    • mysql子查询很糟糕,不会将子查询结果集给到外层,而是外层结果先查出来,然后逐条执行匹配子查询
  • DERIVED:在FROM列表中包含的子查询
  • UNION:出现在union后的查询语句中
  • UNION RESULT:从UNION表获取结果集

table


含义:表示这条查询语句所查询的数据表或结果集。
  • 查询使用了别名,那么这里显示的是别名
  • 不涉及对数据表的操作,那么这显示为null
  • 显示为< derivedN >就表示这个是临时表,后边的N就是执行计划中的id,表示结果来自该id查询结果。
  • 如果是尖括号括起来的<unionM,N>,也是一个临时表,表示这个结果来自于union查询的id为M,N的结果集。

解读select_type和table

例子
EXPLAIN
select *,(select 1 from t_role) as 'role',
 (select name from t_user where user_no = ru.user_no) as 'name'   
from 
 (select * from t_role_user) ru 
UNION
select *,'role','name' from t_role_user;

在这里插入图片描述

解析执行计划
  • 第一行:第一个select ,id为1则执行顺序为倒数,PRIMARY该查询为外层查询,table列为derived4,表示查询的结果集来自一个衍生表,其中4表示id为4的select
  • 第二行:id 为4,是第二个执行的select(5->4),DERIVED说明from中包含子查询,table为t_role_user表示的查询结果集为t_role_user表。所以就是:(select * from t_role_user) ru 子查询
  • 第三行:DEPENDENT SUBQUERY,table 是t_user 显然语句是,(select name from t_user where user_no = ru.user_no) as ‘name’ 这个语句的结果集依赖于外层表ru的结果集,user_no依赖ru.user_no的结果集。
  • 第四行:SUBQUERY 这边是select中有子查询,table是t_role,语句是(select 1 from t_role) as ‘role’ ,因为他不依赖外层结果集,所以是SUBQUERY
  • 第五行:UNION 关键字后面的一个select ,这边就是 select *,‘role’,‘name’ from t_role_user
  • 第六行:id为null union 结果集。table为<union1,5> 说明是id1和id5的select结果集进行union。
额外的DEPENDENT SUBQUERY

上面第三行的DEPENDENT SUBQUERY,本来就是根据外层结果集作为里层条件查询的,性能在预料之内。但在下面这种情况的DEPENDENT SUBQUERY却是意向不到的,比如:

EXPLAIN
select * from t_role_user 
where role_id  in (select id from t_role );

在这里插入图片描述
这种情况,2依赖于外层1的结果集;并非想象中,先执行select id from t_role 的结果集,再交给role_id in来查询。而是先查询select * from t_role_user 的大结果集,再逐条匹配子结果集(该问题在5.6版本之后就优化了)。

type


含义:访问类型;表示MySQL在表中找到所需行的方式
常见类型:

在这里插入图片描述

性能:左–>右,差–>好
  • ALL:Full Table Scan, MySQL将遍历全表以找到匹配的行;全表扫描
EXPLAIN select * from t_user where name = '';

在这里插入图片描述

  • index:Full Index Scan,index与ALL区别是index遍历索引树。
EXPLAIN select id from t_user;

在这里插入图片描述

  • range:索引范围扫描,对索引的扫描开始于某一点,返回匹配值域的行;常见于between,< >等的查询
// 根据不同的情况,同样类型的range,性能会有差异
EXPLAIN select * from t_user where id between 0 and 80;
EXPLAIN select * from t_user where id >=0 and age <= 80;
EXPLAIN select * from t_user where id in (0,30,50);

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • ref:非唯一性索引扫描,返回匹配某个单独值的所有行。
EXPLAIN select * from t_user where age = 3;

在这里插入图片描述

  • eq_ref:唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配。常见于主键或唯一索引扫描。
EXPLAIN select * from t_role r join t_role_user ru on r.id = ru.id;

在这里插入图片描述

  • const / system:使用主键或者唯一索引,且匹配的结果只有一条记录,常出现于where条件是=的情况。system是const类型的特例,查询的表本身只有一行。
EXPLAIN select * from (select * from t_role where id = 1) as rs;

在这里插入图片描述

  • NULL:MySQL在优化过程中分解语句,执行时甚至不用访问表或索引。
EXPLAIN select min(id) from t_role;

在这里插入图片描述

possible_keys


含义:可能使用的索引
  • 可能使用的索引,注意不一定会使用。
  • 查询涉及到的字段上若存在索引,则该索引将被列出来。
  • 当该列为NULL时就要考虑当前的SQL是否需要优化了。

key


含义:实际使用的索引
  • 显示MySQL在查询中实际使用的索引,若没有使用索引,显示为NULL。
  • 查询中若使用了覆盖索引(覆盖索引:索引的数据覆盖了需要查询的所有数据),则该索引仅出现在key列表中,而possible_keys为NULL
EXPLAIN select user_no from t_user ;

在这里插入图片描述

  • select_type为index_merge时,这里可能出现两个以上的索引,其他的select_type这里只会出现一个。

key_len


含义:表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度

ref


含义:表示表的连接匹配条件,即哪些列或常量被用于查找索引列上的值
  • 如果是使用的常数等值查询,这里会显示const
  • 如果是连接查询,被驱动表的执行计划这里会显示驱动表的关联字段
  • 如果是条件使用了表达式或者函数,或者条件列发生了内部隐式转换,这里可能显示为func
EXPLAIN select * from t_role r join t_role_user ru on r.id = ru.id 

在这里插入图片描述
从结果看,连接查询,关联的是r表的id字段。并且key_len为8,说明定长的8个字节。
所以:key_len显示的值为索引字段的最大可能长度,并非实际使用长度,即key_len是根据表定义计算而得,不是通过表内检索出的

rows


含义:返回估算的结果集数目,注意这并不是一个准确值。

extra


含义:包含不适合在其他列中显示但十分重要的额外信息
  • Using index:查询中使用了覆盖索引(Covering Index)
    • 覆盖索引:包含所有满足查询需要的数据的索引
    • 利用索引返回select列表中的字段,而不必根据索引再次读取数据文件
    • 如果要使用覆盖索引,一定要注意select列表中只取出需要的列,不可select *
EXPLAIN select age from t_user

在这里插入图片描述

  • Using where:用where子句来过滤结果集
EXPLAIN select * from t_user  where age = 1

在这里插入图片描述

  • Using filesort:使用文件排序,使用非索引列进行排序时出现,非常消耗性能,尽量优化。
EXPLAIN select * from t_user where age=3 order by creator

在这里插入图片描述

EXPLAIN select * from t_user where age=3 order by age

在这里插入图片描述

  • Using temporary:使用了临时表,常见于排序和分组查询
EXPLAIN select ru.user_no from t_role r join t_role_user ru on r.id = ru.id GROUP BY ru.user_no

在这里插入图片描述

EXPLAIN select r.role_name from t_role r join t_role_user ru on r.id = ru.id GROUP BY r.role_name

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值