order by优化:
order by使用filesort,索引对结果集进行排序。这里介绍一下,使用索引排序的情况,以及不使用索引的情况。
使用索引的情况:
1.当order by未使用的(索引)字段,是常量时(在where子句中);
2.满足最左前缀时;
3.如果索引不包含所要查询的所有列时,只有在访问索引较为高效时才会使用索引,在确定查询计划时MySQL会对情况进行分析。如:
select part1 from t1 order by part1,part2
其中索引未(part1,part2)。由于索引时基于B树的(M有ISAM表是B树,InnoDB是B+树),按索引字段都是有序的。此时使用索引,较为高效。
另对于,
select * from t1 order by part1,part2
此时若是使用索引,用索引完成order by操作,然后根据这些字段去表里查找对应的数据的其他字段。这种情况下不如直接对表进行filesort。
根据以上描述的情况是MyISAM表,如果是InnoDB表呢?
如果是InnoDB表,此时根据索引先找到对应的主键,然后根据主键在聚簇索引里找到对应的数据行。
4.对于select * from t1 where part1 = constant order by part2;
where子句使一个索引查询较为高效,则会使用索引。此查询where限定了part1,是访问到的数据行都是按part2(使用索引的话)排序的。
对于以下的情况,是不使用索引需要执行器进行分析,也就是说这种情况下是不确定的跟具体的数据(特点,数据量的大小等等)有关:
1.select * from t1 where part1 > constant order by part1.
个人认为,在InnoDB中,会使用索引,首先从where,order by操作后的结果集通过主键索引查找对应的数据行,此时较为高效,会使用索引。
在MyISAM中,根据结果集进行遍历表,或者直接对表进行filesort,执行引擎具体会选择哪种要根据具体情况分析。
2.select * from t1 where part1 = constant1 and part2 > constant2 order by part2
使用索引。一定吗?未必,part2如果有很多行,多到使用索引并没有带来明显效率的提升。
不使用索引的情况:
1.order by后跟的字段不在同一个索引中,或者不连续,或者排序不一致,比如,order by part1 desc,part2 asc;
2.order by后跟的列使用表达式时,使用函数时,字段首字母为%,order by,group by的列不一致时;
3.别名的设置,可能导致不能使用索引,如:
select abs(a) as a
from t
order by a;
t.a有索引,但是select出来的结果集,a已经变成了abs(a)这是没有索引的。
当,
select abs(a) as b
from t
order by a;
这种情况下使用索引。
4.如果group by,order by后面跟的列相同时,MySQL会对其进行两次sort,但是不会带来性能的损失,可以使用order by null来抑制order b的排序。