天天看点

MySQL - order by排序优化

排序优化:order by(索引不再用于查询,而是用于排序了)(order by默认升序)

一句话:索引建的好,对order by的语句也有影响,怎么看这个关于order by的语句建立的好不好:根据Explain中Extra列是否显示Using filesort(显示了就不好)

Using index(扫描有序索引排序) 和 Using filesort(文件排序),前者好,后者意味着order by 的列名(个数、顺序、种类)有些问题。

Using filesort时,就没有使用索引提供好的顺序,而是自己又进行了一次排序,这种排序有两种算法:

1.双路排序

使用在MYSQL4.1之前,扫描磁盘(IO)两次:根据行指针,第一次扫出order by的列名的指,排序,第二次再根据排好的顺序所对应的行指针,在磁盘里进行扫描,以输出结果。

2.单路排序

MySQL - order by排序优化

但是单路排序也有出问题的时候,这个时候就会偷鸡不成蚀把米:

即sort_buffer不够用的时候(里面存的是待排序的很多行完整的数据)。

解决办法(MYSQL服务器的参数调优):

1.提高sort_buffer_size参数设置提高;(指缓存的总容量)

2.max_length_for_sort_data参数设置;(指每行数据的最大上限)

(即这两者共同制约,决定使用哪种排序算法:双路or单路)

3.少用select *(因为查出的所有东西(每行的完整数据)都会放心buffer里,select *就很可能快速把buffer撑爆)

MySQL - order by排序优化

即如果排序(order by) 和 查询(where) 使用了相同索引,就不会出现Using filesort。

但是要注意的是 是where 和 order by 可以相互结合(而非select的内容 和 order by 相互结合),和select,即你要查什么毫无关系!

小总结:ORDER BY 子句尽量使用Index方式排序,避免使用FileSort方式排序,尽可能在索引列上完成排序操作,遵照索引键的最佳左前缀。如果不在索引列上,FileSort有两种算法,Mysql就要启动双路排序和单路排序。

举例:

此例的一个前提:建立了一个idx_a_b_c的联合索引

MySQL - order by排序优化

感觉是那个意思,即在where中指定了a为常量(但是当a为范围时(如 a in(...)、a >1这种),a作为大哥并不好使用,与a=常量完全不一样!),那么b、c就可以接在a后面,即此时order by也能够使用到索引;

注意一下上面的红框,即这里也能使用哦~

MySQL - order by排序优化

只看红框就够了:虽然默认order by升序,但是只要保持一致,也能索引(即全为显示设置为降序时,也能使用索引)

最后总结一下:所谓的排序和查询可以使用相同的索引,这里的查询是指where中的列,和select的内容应该是无关的吧:对的!

MySQL - order by排序优化