Explain关键字 什么是MySQL的执行计划?( 二 )


【type列】 
type列的结果表明当前行对应的select的关联类型或访问类型 , 也就是优化器决定怎么查找数据表中的行 , 以及查找数据行记录的大概范围 。该列的取值优化程度的优劣 , 从最优到最差依次为:null>system> const > eq_ref > ref > range > index > ALL 。一般来说 , 要保证查询达到range级别 , 最好达到ref 。
 
1)null , MySQL优化器在优化阶段分解查询语句 , 在优化过程中就已经可以得到结果 , 那么在执行阶段就不用再访问表或索引 。
explain select min(user_id) from t_user;

Explain关键字 什么是MySQL的执行计划?

文章插图
 
这时的函数min , 在索引列user_id中选取最小值 , 可以直接查找索引来完成 , 不需要执行时再访问数据表 。
 
2)const和system:const出现在用 primary key(主键) 或 unique key(唯一键) 的所有列与常数比较时 , 优化器对查询进行优化并将其部分查询转化成一个常量 。最多有一个匹配行 , 读取1次 , 速度非常快 。而system是const的特例 , 表中数据只有一条匹配时为system 。此时可以用explain extended+show warnings查看执行结果 。
 
explain extended select * from (select * from t_user where user_id = 1) tmp;
【Explain关键字 什么是MySQL的执行计划?】 
show warnings;
Explain关键字 什么是MySQL的执行计划?

文章插图
 

Explain关键字 什么是MySQL的执行计划?

文章插图
 
MySQL5.7及以后版本优化后:
Explain关键字 什么是MySQL的执行计划?

文章插图
 

Explain关键字 什么是MySQL的执行计划?

文章插图
 
3)eq_ref:primary key(主键)或 unique key(唯一键) 索引的所有构成部分被join使用  , 只会返回一条符合条件的数据行 。这是仅次于const的连接类型 。
 
explain select * from t_group_user gu left join t_group g ong.group_id = gu.group_id;
Explain关键字 什么是MySQL的执行计划?

文章插图
 
4) ref:与eq_ref相比 , ref类型不是使用primary key(主键) 或 unique key(唯一键)等唯一索引 , 而是使用普通索引或者联合唯一性索引的部分前缀 , 索引和某个值相比较 , 可能会找到符合条件的多个数据行 。
 
1. 如下示例 , 使用的group_name是普通索引
 
explain select * from t_group where group_name= 'group1';
Explain关键字 什么是MySQL的执行计划?

文章插图
 
2.关联表查询
 
explain select g.group_id from t_group gleft join t_group_user gu on gu.group_id = g.group_id;
Explain关键字 什么是MySQL的执行计划?

文章插图
 
5)range:出现在 in(),between ,> ,<, >= 等操作符中 。使用一个索引来查询给定范围的行 。
 
6)index:扫描全表索引(index是从索引中读取的,所有字段都有索引 , 而all是从硬盘中读取) , 比ALL要快 。
 
explain select * from t_group;
Explain关键字 什么是MySQL的执行计划?

文章插图
 
7)all:即全表扫描 , 需要从头到尾去查找所需要的行 。一般这种情况下这需要增加索引来进行查询优化了
 
explain select * from t_user;
 
Explain关键字 什么是MySQL的执行计划?

文章插图
 
【possible_keys列】 
这一列的结果表明查询可能使用到哪些索引 。但有些时候也会出现出现possible_keys 列有结果 , 而 后面的key列显示 null 的情况 , 这是因为此时表中数据不多 , 优化器认为查询索引对查询帮助不大 , 所以没有走索引查询而是进行了全表扫描 。
 
如果possible_keys列的结果是null , 则表明没有相关的索引 。这时 , 可以通过优化where子句 , 增加恰当的索引来提升查询性能 。
【key列】 
这一列表明优化器实际采用哪个索引来优化对该表的访问 。如果没有使用索引 , 则该列是 null 。


推荐阅读