mysql中有两种常用的排序方式
1.通过有序索引顺序扫描直接返回有序数据
这种方式在使用explain分析时显示为using index,不需要额外的牌序,操作效率较高
2.通过对返回数据进行排序,即filesort
所有不通过索引直接返回排序结果的排序都是filesort排序
filesort通过相应的排序算法,将取得的数据在sort_buffer_size系统变量设置的内存排序区中进行排序,如果内存装载不下,会将磁盘上的数据进行分块,再对各个数据块进行排序,再将各个块合并成有序的结果集。
了解了mysql的排序方式,就有了优化的原则:即尽量减少额外的排序,通过索引直接返回有序数据。
①where条件和order by使用相同的索引
②order by的顺序和索引顺序相同
③orderby的字段都是升序或者降序
否则要进行额外的排序操作,会出现fiesort
举例:
一下几种情况不使用索引做排序操作
select * from tabname order by key1 desc ,key2 asc;#混合了升序和降序查询
select * from tabname where key2=contant order by key2;#用于查询行的关键字与order by中所使用的不同
select * from tabname order by key1,key2;#对不同关键字使用order by
对于filesort排序方式的优化
虽然通过创建索引可以减少filesort排序方式的出现,但有时仍不可避免,因此需要想办法加快filesort的操作
1.两次扫描算法
2.一次扫描算法
适当加大系统变量max_length_for_sort_data能够让mysql选择更优化的filesort排序方法,但如果设置过大会造成CPU利用率过低和磁盘I/O过高,
适当加大sort_buffer_size排序区,尽量让排序在内存中完成,而不是通过创建临时表放在文件中进行,但也不能无限加大sort_buffer_size排序区,因为改参数是每个线程独占的,设置过大,会导致服务器swap严重,要考虑数据库活动连接数和服务器内存的大小来适当设置排序区。
减少select *的试用,可减少排序区使用,提升sql性能