Mysql 慢查询 分析
文章目录
explain分析执行计划
通过上一篇文章的方法查询到执行效率低的SQL语句后,可以通过explain或者desc命令获取Mysql如何执行selec语句的信息,包括在执行过程汇总表如何连接和连接的顺序等信息。
explain select * from tb_item where id = 1;
字段 | 含义 |
---|---|
id | select查询的序列号,表示查询中执行selec子句或操作表的顺序 |
select_type | 表示selec的类型,常见的取值有SIMPLE(简单表,不使用子查询)、PRIMARY(主查询,即外层的查询)、UNION(UNION中的第二个或者后面的查询语句)、SUBQUERY(子查询中的第一个selec)等 |
table | 输出结果集的表 |
type | 表示表的连接类型,性能由好到差的链接类型为(system–>const–>eq_ref–>ref–>ref_or_null–>index_merge–>index_subquery–>range–>index–>all) |
possible_keys | 表示查询时,可能使用的索引 |
key | 表示实际使用的索引 |
key_len | 索引字段的长度 |
rows扫描行的数量 | |
extra | 执行情况的说明和描述 |
explain之id
id字段是selec查询的序列号,查询的序列号,表示查询中执行selec子句或操作表的顺序
1)id相同表示加载表的顺序是从上到下
explain select * from t_role r,t_user u,user_role ur where r.id = ur.role_id and u.id = ur.user_id;
2)id不同,id值越大,优先级越高,越先被执行
explain select * from t_role where id = (select role_id from user_role where user_id = (select id from t_user where username = 'stu1'))
3)id有相同,也有不同,同时存在。
id相同的可以认为是一组,从上到下顺序执行;在所有组中,id值越大,优先级越高,越先执行
explain之select_type
表示select的类型,常见的取值,如下表所示
select_type | 含义 |
---|---|
SIMPLE | 简单的select查询,查询中不包含子查询或者UNION |
PRIMARY | 查询中包含任何复杂的子查询,最外层查询标记为改标记 |
SUBQUERY | 在SELECT或WHERE列表中包含了子查询 |
DERIVED | 在FROM列表中包含的子查询,被标记为DERIVED(衍生)MYSQL会递归执行这些子查询,把结果放在临时表中 |
UNION | 若第二个SELECT出现在UNION之后,则标记为UNION;若UNION包含在 FROM子句的子查询中,外层SELECT将被标记为:DERIVED |
UNION RESULT | 从UNION表获取结果的SELECT |
从上到下,效率越来越低
SUBQUERY演示
explain select * from t_user where id = (select id from user_role where role_id = 9);
DERIVED演示
explain select a.* from (select * from t_user where id in (1,2)) a;
UNION演示
explain select * from tb_user where id = 1 union select * from tb_user where id = 2;
explain之table
展示这一行的数据是关于哪一张表的
explain之type
type显示的是访问类型,是较为重要的指标,取值为
type | 含义 |
---|---|
null | Mysql不访问任何表,索引,直接返回结果 |
system | 表只有一行记录,这是const类型的特例,一般不会出现 |
const | 表示通过索引一次就找到了,const用于比较primary key或者unique索引。因为只匹配一行数据,所以很快,如将主键置于where列表汇总,Mysql就能将该查询转换为一个常量,cosnt于将"主键"或"唯一"索引的所有部分与常量进行比较 |
eq_ref | 类似ref,区别在于使用的是唯一所有,使用主键的关联查询,关联查询出的记录只有一条,常见于主键或唯一索引扫描 |
ref | 非唯一性索引扫描,返回匹配某个单独值的所有行。本质上也是一种索引访问,返回所有匹配某个单独之的所有行(多个) |
range | 只检索给定返回的行,使用一个索引来选择行,where之后出现between,<,>,in 等操作 |
index | idnex与all的区别为index类型只是遍历了索引树,通常比all快,all是遍历数据文件 |
all | 将遍历全表以找到匹配的行 |
null演示
system演示
const演示
explain之key
- possible_keys:显示可能应用在这张表的索引,一个或多个
- key:实际使用的索引,如果为NULL,则没有使用索引
- key_len:表示索引中使用的字节数,该值为索引字段最大可能长度,并非实际使用长度,在不损失精确性的前提下,长度越短越好
explain之rows
扫描行的数量
explain之extra
其他额外的执行计划信息,在改列展示
extra | 含义 |
---|---|
using filesort | 说明mysql会对数据使用一个外部的索引排序,而不是按照表内的索引进行读取,称为“文件排序”,效率低 |
using temporary | 使用了临时表保存中间结果,MySQL在对查询结果排序时使用临时表。常见于order by和group by,效率低 |
using index | 表示相应的select操作使用了覆盖索引,避免访问表的数据行,效率不错 |
show profile分析SQL
查询sql的具体耗时步骤