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


explain select * from t_group where group_name = 'group1';
什么是MySQL的执行计划(Explain关键字)?文章插图
4)null:被查询的列没有被索引覆盖 , 但where条件是索引的前导列 , 此时用到了索引 , 但是部分列未被索引覆盖 , 必须通过“回表查询”来实现 , 不是纯粹地用到了索引 , 也不是完全没用到索引
explain select * from t_user where user_id='1';
什么是MySQL的执行计划(Explain关键字)?文章插图
5)using index condition:与using where类似 , 查询的列不完全被索引覆盖 , where条件中是一个前导列的范围;这种情况未能通过示例显现 , 可能跟MySQL版本有关系 。
6) using temporary:这表明需要通过创建临时表来处理查询 。 出现这种情况一般是要进行优化的 , 用索引来优化 。 创建临时表的情况:distinct , group by , orderby , 子查询等
explain select distinct user_name from t_user;
什么是MySQL的执行计划(Explain关键字)?文章插图
explain select distinct group_name fromt_group; --group_name是索引列
什么是MySQL的执行计划(Explain关键字)?文章插图
7) usingfilesort:在使用order by的情况下出现 , mysql会对结果使用一个外部索引排序 , 而不是按索引次序从表里读取行 。 此时mysql会根据连接类型浏览所有符合条件的记录 , 并保存排序关键字和行指针 , 然后排序关键字并按顺序检索行信息 。 这种情况下要考虑使用索引来优化的 。
explain select * from t_user orderby user_name;
什么是MySQL的执行计划(Explain关键字)?文章插图
explain select * from t_group order bygroup_name; --group_name是索引列
什么是MySQL的执行计划(Explain关键字)?文章插图
查询优化建议结合前面的描述 , 首先看 type列的结果 , 如果有类型是 all 时 , 表示预计会进行全表扫描(fulltable scan) 。 通常全表扫描的代价是比较大的 , 建议创建适当的索引 , 通过索引检索避免全表扫描 。
再来看下 Extra 列的结果 , 如果有出现 Using temporary 或者 Using filesort 则要多加关注:
Using temporary , 表示需要创建临时表以满足需求 , 通常是因为GROUP BY的列没有索引 , 或者GROUP BY和ORDER BY的列不一样 , 也需要创建临时表 , 建议添加适当的索引 。
Using filesort , 表示无法利用索引完成排序 , 也有可能是因为多表连接时 , 排序字段不是驱动表中的字段 , 因此也没办法利用索引完成排序 , 建议添加适当的索引 。
Using where , 通常是因为全表扫描或全索引扫描时(type 列显示为 ALL 或index) , 又加上了WHERE条件 , 建议添加适当的索引 。
索引使用情况分析数据库表主键索引:demo_id
联合索引:c1,c2,c3
什么是MySQL的执行计划(Explain关键字)?文章插图
实例说明实例一:explain select * from t_demo where c1='d1'and c2='d2' and c3='d3';
explain select * from t_demo where c2='d2'and c1='d1' and c3='d3';
explain select * from t_demo where c3='d3'and c1='d1' and c2='d3';
什么是MySQL的执行计划(Explain关键字)?文章插图
几个Sql表现一致
type=ref,ref=const,const,const
执行常量等值查询时 , 改变索引列的顺序并不会更改explain的执行结果 , 优化器会进行优化 , 推荐按照索引顺序列编写sql语句 。
实例二:
explain select * from t_demo where c1='d1'and c2>'d2' and c3='d3';
什么是MySQL的执行计划(Explain关键字)?文章插图
explain select * from t_demo where c1='d1'and c3>'d3' and c2='d2';
什么是MySQL的执行计划(Explain关键字)?文章插图
第一个例子范围右侧索引失效 , 使用到了两个索引 。
第二个例子 , 由于优化器优化的原因 , 使用到了全部的三个索引 。
实例三:explain select * from t_demo wherec1>'c' and c2='d2' and c3='d3';
什么是MySQL的执行计划(Explain关键字)?文章插图
explain select * from t_demo wherec1>'e' and c2='d2' and c3='d3';
什么是MySQL的执行计划(Explain关键字)?文章插图
从上面两个实例可以发现 , 同样使用最左的索引列范围查询 , 有些情况未用到索引 , 做了全表扫描(第一个例子);有些情况使用到了索引(第二个例子) 。
经反复验证 , 发现如下规律(不一定可靠) , 也可能与数据的第一行或最小值相关 。