1、MySQL支持两种方式的排序filesort和index,Using index是指MySQL扫描索引本身完成排序。index效率高,filesort效率低。
2、order by满足两种情况会使用Using index。
1) order by语句使用索引最左前列 && 查询的字段被索引覆盖覆盖。
2) 使用where子句与order by子句条件列组合满足索引最左前列&& 查询的字段被索引覆盖覆盖。
3、尽量在索引列上完成排序,遵循索引建立(索引创建的顺序)时的最左前缀法则。
4、如果order by的条件不在索引列上,就会产生Using filesort。
5、能用覆盖索引尽量用覆盖索引
6、group by与order by很类似,其实质是先排序后分组,遵照索引创建顺序的最左前缀法则。对于group by的优化如果不需要排序的可以加上order by null禁止排序。注意,where高于having,能写在where中的限定条件就不要去having限定了。
- 联合索引中间字段排序也可以使用到索引---where 和 order by中的所有条件满足联合索引即可
EXPLAIN SELECT * from employees_inndb WHERE NAME = 'LiLei' and position = 'dev' ORDER BY age
- 联合索引中间字段和后面字段排序也可以使用到索引
EXPLAIN SELECT * from employees_inndb WHERE NAME = 'LiLei' ORDER BY age,position
- 联合索引不满足最左前缀原理--跳过字段,无法使用索引会产生filesort
EXPLAIN SELECT * from employees_inndb WHERE NAME = 'LiLei' ORDER BY position
- 联合索引不满足最左前缀原理--order by后面顺序乱了,无法使用索引会产生filesort
EXPLAIN SELECT * from employees_inndb WHERE NAME = 'LiLei' ORDER BY position,age
- 联合索引不满足最左前缀原理--order by后面顺序乱了,但where 条件中age使用常量,可以使用索引,不会产生filesort
分析以下反例为啥没有使用到索引:
- EXPLAIN select * from employees_inndb where name > 'a' order by name;
order by字段上有索引但是 * 没有被索引覆盖
- EXPLAIN select name,age,position from employees_inndb where name in ('LiLei','zhuge') order by position
对于排序来说,多个相等条件也是范围查询