MySQL filesort原理及优化( 二 )


3、根据索引key排序
4、读取排序完成的文件 , 并直接根据数据位置读取数据返回客户端 , 而不是去访问表
特点单路排序一次性将结果读取出来 , 然后在sort buffer中排序 , 避免了双路排序的两次读的随机IO 。
这也有一个问题:当获取的列很多的时候 , 排序起来就很占空间 , 因此 , max_length_for_sort_data变量就决定了是否能使用这个排序算法 。
MySQL根据sort_buffer_size来判断是否使用磁盘临时文件 , 如果需要排序的数据能放入sort_buffer_size则无需使用磁盘临时文件 , 此时explain只会输出using filesort否则需要使用磁盘临时文件explain会输出using temporary;using filesort 。
03
选择
MySQL主要通过比较我们所设定的系统参数max_length_for_sort_data的大小和Query语句所取出的字段类型大小总和来判定需要使用哪一种排序算法 。
如果需要的列数据一行可以放入max_length_for_sort_data则使用一遍扫描否则使用两遍扫描(如果max_length_for_sort_data更大 , 则使用第二种优化后的算法 , 反之使用第一种算法) 。所以如果希望ORDER BY操作的效率尽可能的高 , 一定要注意max_length_for_sort_data参数的设置 。
如果数据库出现大量的排序等待 , 造成系统负载很高 , 而且响应时间变得很长 , 可以考虑是否为MySQL 使用了传统的第一种排序算法而导致 , 在加大了max_length_for_sort_data参数值之后 , 系统负载是否马上得到了大的缓解 , 响应是否快很多 。
04
优化
对于文件排序的优化 , 应该让MySQL避免使用第一种双路排序 , 尽量选择使用第二种单路算法来进行排序 。这样可以减少大量的随机IO操作 , 很大幅度地提高排序工作的效率 。
1、加大max_length_for_sort_data参数的设置
在MySQL中 , 决定使用老的双路排序算法还是改进版单路排序算法是通过参数max_length_for_ sort_data来决定的 。当所有返回字段的最大长度小于这个参数值时 , MySQL就会选择改进后的单路排序算法 , 反之 , 则选择老式的双路排序算法 。所以 , 如果有充足的内存让MySQL存放需要返回的非排序字段 , 就可以加大这个参数的值来让MySQL选择使用改进版的排序算法 。
2、去掉不必要的返回字段或列长度尽量小一些
对于内存不是非常充裕的情况 , 不能强行增大配置项max_length_for_sort_data , 否则可能会造成MySQL不得不将数据分成很多段 , 然后进行排序 , 这样可能会得不偿失 。此时可以选择去掉不必要的返回字段或者将列长度尽可能设置小一些 , 让返回结果长度适应max_length_for_sort_data参数的限制 。
3、增大sort_buffer_size参数设置
增大sort_buffer_size并不是为了让MySQL选择改进版的单路排序算法 , 而是为了让MySQL尽量减少在排序过程中对需要排序的数据进行分段 , 因为分段会造成MySQL不得不使用临时表来进行交换排序 。
4、增加read_rnd_buffer_size大小 , 可以一次性多读到内存中
该变量可以被任何存储引擎使用 , 当从一个已经排序的键值表中读取行时 , 会先从该缓冲区中获取而不再从磁盘上获取 。默认为256K 。
5、改变tmpdir , 使其指向多个物理盘(不是分区)的目录 。
05
总结
当看到MySQL的explain输出using filesort时 , 说明排序时没有使用索引 。如果输出using temporary;using filesort则说明使用文件排序和磁盘临时表 , 这种情况需要引起注意 , 效率会比较低 。

推荐阅读