🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
![](https://img.kancloud.cn/6c/ab/6cab1b652f5d2b31b9ce7c6637d2fe99_1551x159.png) ![](https://img.kancloud.cn/0c/63/0c639c1d33ed16bfcf412e044e0f45e8_1532x292.png) orderby满足两种情况,会使用Index方式排序 1. orderby语句使用索引最左前列 2. 使用where子句与orderby子句条件列组合满足索引最左前列 如果不在索引列,filesort有两种算法:双路排序和单路排序 **双路排序**: mysql之前是使用双路排序,要扫两次磁盘,最终得到数据.读取行指针和orderby列,对他们进行排序,然后扫描已经排序好的列表,按照列表中的值重新从列表中读取对应的数据输出.从磁盘取排序字段,在buffer进行排序,再从磁盘取其他字段. **单路排序**: 从磁盘读取查询所需要列,按照orderby列在buffer对他们进行排序,然后扫描排序后的列表进行输出,它的效率更快一些,避免第二次读取数据.变为顺序IO,但是会使用更多空间,因为把每一行都保存到内存中了. **单路排序问题**: 在`sort_buffer`中,方法B比方法A要占用更多空间,因为方法B是把所有字段都取出,所以有可能取出的数据的总大小超出了`sort_buffer`的容量,导致每次只能取出`sort_buffer`容量大小的数据,进行排序(创建tmp文件,多路合并),排完再取`sort_buffer`容量带下,再排...,从而导致多次IO. 本来想一次IO,反而导致了多次IO操作,得不偿失. **单路优化策略** * 增大`sort_buffer_size`参数的设置 * 增大`max_length_for_sort_data`参数的设置 **提高orderby排序** 1. orderby中`select *`是不好的 2. 当query字段大小总和小于`max_length_for_sort_data`而且排序字段不是TEXT|BLOB类型时,会用改进后的算法-单路排序,否则用老算法,多路排序 3. 两种算法都有可能超出sort_buffer的容量,超出之后,会创建tmp文件进行合并排序,导致多次IO.单路风险更大一点 4. 尝试提高`sort_buffer_size`,这个参数是针对每个线程的 5. 尝试提高`max_length_for_sort_data` **为排序使用索引** `key a_b_c (a,b,c)` orderby能使用索引最左前缀 ~~~ order by a desc, b desc, c desc ~~~ 如果where使用索引的最左前缀定义为常量,则orderby能使用索引 ~~~ where a = const order by b, c where a = const and b = const order by c where a = const order by b, c where a = const and b > const order by b, c ~~~ 不能使用索引 ~~~ order by a asc, b desc, c desc //排序不一致 where g = const order by b, c //丢失a索引 where a = const order by c //丢失b索引 where a = const order by a, d //d不是索引一部分 where a in (...) order by b, c //对于排序来说,多个相等条件也是范围查询 ~~~