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


 
Using filesort , 表示无法利用索引完成排序 , 也有可能是因为多表连接时 , 排序字段不是驱动表中的字段 , 因此也没办法利用索引完成排序 , 建议添加适当的索引 。
 
Using where , 通常是因为全表扫描或全索引扫描时(type 列显示为 ALL 或index) , 又加上了WHERE条件 , 建议添加适当的索引 。
索引使用情况分析数据库表 
主键索引:demo_id
联合索引:c1,c2,c3

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

文章插图
 
实例说明实例一: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';
Explain关键字 什么是MySQL的执行计划?

文章插图
 
几个Sql表现一致
type=ref,ref=const,const,const
执行常量等值查询时 , 改变索引列的顺序并不会更改explain的执行结果 , 优化器会进行优化 , 推荐按照索引顺序列编写sql语句 。
 
实例二:
explain select * from t_demo where c1='d1'and c2>'d2' and c3='d3';
Explain关键字 什么是MySQL的执行计划?

文章插图
 
explain select * from t_demo where c1='d1'and c3>'d3' and c2='d2';
Explain关键字 什么是MySQL的执行计划?

文章插图
 
第一个例子范围右侧索引失效 , 使用到了两个索引 。
第二个例子 , 由于优化器优化的原因 , 使用到了全部的三个索引 。
实例三:explain select * from t_demo wherec1>'c' and c2='d2' and c3='d3';
Explain关键字 什么是MySQL的执行计划?

文章插图
 
explain select * from t_demo wherec1>'e' and c2='d2' and c3='d3';
Explain关键字 什么是MySQL的执行计划?

文章插图
 
从上面两个实例可以发现 , 同样使用最左的索引列范围查询 , 有些情况未用到索引 , 做了全表扫描(第一个例子);有些情况使用到了索引(第二个例子) 。
 
经反复验证 , 发现如下规律(不一定可靠) , 也可能与数据的第一行或最小值相关 。
1. 跟存储的数据有关
2. 在大于条件下 , 如果条件数据小于列数据 , 则索引无效;如果条件数据大于列数据 , 则索引有效;
 
在设计查询条件时 , 请注意规避 。
针对第一个例子 , 可以采用覆盖索引的方式优化 。
实例四:explain select * from t_demo where c1='d1'and c2='d2' order by c3;
Explain关键字 什么是MySQL的执行计划?

文章插图
 
explain select * from t_demo where c1='d1'order by c3;
Explain关键字 什么是MySQL的执行计划?

文章插图
 
explain select * from t_demo where c1='d1'and c3='d3' order by c2;
Explain关键字 什么是MySQL的执行计划?

文章插图
 
order by排序使用到索引和没使用到索引的情况
实例五:explain select * from t_demo where c1='d1'and c4='d4' order by c1,c2;
Explain关键字 什么是MySQL的执行计划?

文章插图
 
条件列包含没有索引的列 , 出现了Using filesort
实例六:explain select * from t_demo where c1='d1'and c4='d4' group by c1,c2;
Explain关键字 什么是MySQL的执行计划?

文章插图
 
性能非常差的场景 , 同时出现了Using temporary和Using filesort
总结 
1. 两种方式的排序filesort和index , Usingindex是指MySQL扫描索引本身完成排序 。index效率高 , filesort效率低 。
 
2. order by满足两种情况会使用Using index 。
1)order by语句使用索引最左前列 。
2)使用where子句与order by子句条件列组合满足索引最左前列 。
 
3. 尽量在索引列上完成排序 , 遵循索引建立(索引创建的顺序)时的最佳左前缀法则 。


推荐阅读