where 条件和 on 的判断这些过滤条件,作为优先优化的部分,是要被先考虑的!
其次,如果有分组和排序,那么 也要考虑 grouo by 和 order by。


1. 必须有过滤,才会用到索引

结论:where,limt 都相当于一种过滤条件,所以才能使用上索引!

mysql先命中索引再排序 mysql order by where索引优先级_mysql先命中索引再排序

2. 顺序不要错,否则会产生 Using filesort(需要优化) 

explain select * from emp where age=45 order by deptid,name;

mysql先命中索引再排序 mysql order by where索引优先级_数据库_02

explain select * from emp where age=45 order by deptid,empno;

empno 字段并没有建立索引,因此也无法用到索引,此字段需要排序!

mysql先命中索引再排序 mysql order by where索引优先级_数据库_03

explain select * from emp where age=45 order by name,deptid;

where 两侧列的顺序可以变换,效果相同,但是 order by 列的顺序不能随便变换!

mysql先命中索引再排序 mysql order by where索引优先级_sql_04

explain select * from emp where deptid=45 order by age;

deptid 作为过滤条件的字段,无法使用索引,因此排序没法用上索引

mysql先命中索引再排序 mysql order by where索引优先级_mysql_05

 3. order by方向不一致,必会产生 Using filesort(需要优化) 

explain select * from emp where age=45 order by deptid desc, name desc ; (推荐)

如果可以用上索引的字段都使用正序或者逆序,实际上是没有任何影响的,无非将结果集调换顺序。

mysql先命中索引再排序 mysql order by where索引优先级_mysql_06

explain select * from emp where age=45 order by deptid asc, name desc ;

如果排序的字段,顺序有差异,就需要将差异的部分,进行一次倒置顺序,因此还是需要手动排序的!

mysql先命中索引再排序 mysql order by where索引优先级_数据库_07

4. 索引的选择 idx_age_name 和 idx_age_empno

为什么不建3个字段的索引

create index idx_age_empno_name on emp(age,empno,name);

原因: empno 是范围查询,因此导致了索引失效,所以 name 字段无法使用索引排序。


create index idx_age_name on emp(age,name); 

create index idx_age_empno on emp(age,empno); [这里这个索引更好]

mysql先命中索引再排序 mysql order by where索引优先级_索引_08


explain SELECT SQL_NO_CACHE * FROM emp use index(idx_age_name) WHERE age =30 AND empno <101000 ORDER BY NAME ;

mysql先命中索引再排序 mysql order by where索引优先级_索引_09


结论: 当范围条件和 group by 或者 order by 的字段出现二选一时 ,优先观察条件字段的过滤数量,如果过滤的 数据足够多,而需要排序的数据并不多时,优先把索引放在范围字段上。反之,亦然。 

原因:所有的排序都是在条件过滤之后才执行的,所以如果条件过滤了大部分数据的话,几百几千条数据进行排序 其实并不是很消耗性能,即使索引优化了排序但实际提升性能很有限。 相对的 empno<101000 这个条件如果没 有用到索引的话,要对几万条的数据进行扫描,这是非常消耗性能的,使用 empno 字段的范围查询,过滤性更好 (empno 从 100000 开始)!5. 使用覆盖索引 

覆盖索引:SQL 只需要通过索引就可以返回查询所需要的数据,而不必通过二级索引查到主键之后再去查询数据。

mysql先命中索引再排序 mysql order by where索引优先级_sql_10



6. group by 可以直接使用索引

group by 使用索引的原则几乎跟 order by 一致 ,唯一区别是 groupby 即使没有过滤条件用到索引,也可以直 接使用索引。

mysql先命中索引再排序 mysql order by where索引优先级_mysql_11