首先口径:(无过滤不索引,顺序错必排序,方向反必排序) order by 无过滤不索引, 所以即使没有where 也要有个limit

order by 关键字优化 - 图1

1. Order BY子句,尽量使用Index方式排序,避免使用FileSort方式排序】

  1. Mysql 支持两种方式排序,FileSort Index效率高,它指Mysql扫描索引本身完成排序。FileSort方式效率低
  2. Order by 满足两种情况,会使用Index方式排序
  3. 1 order by 语句使用索引最左前列
  4. 2 使用where子句与order by 子句条件列组合满足索引最左前列

2. 尽可能在索引列上完成排序,遵循索引建的最佳左前缀

3. 如果不在索引列上, filesort有两种算法,mysql就要启动双路排序和单路排序

  1. 双路排序:Mysql4.1之前是双路排序,字面意思就是两次扫描磁盘,最终得到数据,读取行指针和orderby列,对他们进行排序,然后扫描已经排序好的列表,按照表中的值重新从列表中读取对应的数据输出(从磁盘取排序字段,在buffer进行排序,再从磁盘取其他字段取一批数据,要对磁盘进行两次扫描,众所周知,I/O是很耗时的,所以在mysql4.1后出现了第二种改进的算法,就是当路排序
  2. 单路排序:从磁盘读取查询需要的所有列,按照order by 列在buffer对它们进行排序,然后扫描排序后的列表进行输出,它的效率更快一些,避免了第二次读取数据,并且把随机IO变成顺序IO,但时它会使用更多空间,因为它把每一行都保存在内存中了(buffer
  3. 结论及引申出的问题:
  4. 由于单路是后出的,总体而言好过双路
  5. 但是用单路有问题:
  6. sort_buffer中,方法B比方法A要多占很多空间,因为方法B是把所有的字段都取出,
  7. 所以有可能取出的数据总大小超出了sort_buffer的容量,
  8. 导致每次只能取sort_buffer容量大小的数据,
  9. 进行排序(创建他mp文件,多路合并),
  10. 排完再取sort_buffer容量大小,再排....从而多次I/O
  11. (本来想省一次I/O 反而导致了大量I/O,反而得不偿失)

优化策略

  1. 增大sort_buffer_size参数的设置
  2. 增大max_length_for_sort_data参数的设置
    结论:
    order by 关键字优化 - 图2