在看本篇文章时一起跟着操作更有感觉呦~
前期准备
# 创建测试表 |
# 插入一些示例数据 |
案例分析
1. EXPLAIN SELECT * from employees where name = “LiLei” and position =’dev’ ORDER BY age;
结果分析:
上面语句用到联合索引中 name 和 age两个字段。
利用最左前缀法则:中间字段不能断,因此查询用到了name索引,从key_len=74也能看出,age索引列用 在排序过程中,因为Extra字段里没有using filesort(文件排序)。
2. EXPLAIN SELECT * from employees where name = “LiLei” ORDER BY position
结果分析:
从 key_len=74可知查询使用了name索引,由于用了position进行排序,跳过了 age,出现了Using filesort。
3. EXPLAIN SELECT * from employees where name = “LiLei” ORDER BY age,position
结果分析:
key_len=74 得查找只用到索引name;因为无Using filesort,age和position用于排序。
4. EXPLAIN SELECT * from employees where name = “LiLei” ORDER BY age,position
结果分析:
与3中explain的执行结果一样,但是出现了文件排序 Using filesort,因为索引的创建顺序为 name,age,position,但是排序的时候age和position颠倒位置了,不符合最左前缀法则。
5. EXPLAIN SELECT * from employees where name = “LiLei” ORDER BY age,position
结果分析:
与4对比,在Extra中并未出现Using filesort,因为age为常量,在排序中被优化,所以索引顺序未颠倒,符合 最左前缀法则 不会出现Using filesort。
6. EXPLAIN SELECT * from employees where name = “LiLei” ORDER BY age asc,position desc;
结果分析:
虽然排序的字段列与索引顺序一样,且order by默认升序,这里position desc变成了降序,导致与索引的 排序方式不同,从而产生Using filesort。Mysql8以上版本有降序索引可以支持该种查询方式。
7. EXPLAIN SELECT * from employees where name in (“LiLei”,’zhangsan’)ORDER BY age,position;
结果分析:
对于排序来说,多个相等条件也是范围查询
8. EXPLAIN SELECT * from employees where name > ‘a’ ORDER BY name
结果分析:
结合前面的mysql 索引选择 这条语句 经过mysql cost 计算 走的全表扫描 所以没有使用到索引 且使用use filesort。
这种情况可以使用覆盖索引进行优化
总结
MySQL支持两种方式的排序filesort和index,Using index是指MySQL扫描索引本身完成排序。index
效率高,filesort效率低。order by满足两种情况会使用Using index。
- order by语句使用索引最左前列。
- 使用where子句与order by子句条件列组合满足索引最左前列。
尽量在索引列上完成排序,遵循索引建立(索引创建的顺序)时的最左前缀法则。
如果order by的条件不在索引列上,就会产生Using filesort。
能用覆盖索引尽量用覆盖索引
group by与order by很类似,其实质是先排序后分组,遵照索引创建顺序的最左前缀法则。对于group by的优化如果不需要排序的可以加上order by null禁止排序。注意,where高于having,能写在where中 的限定条件就不要去having限定了。
若你觉得我的文章对你有帮助,欢迎点击上方按钮对我打赏
扫描二维码,分享此文章