控制 MySQL 排序的最大字段定义的列总字节长度
- mysql 有两种文件排序算法(双路排序和单路排序),如果需要排序的列的总大小加上 order by 列的大小超过了max_length_for_sort_data 定义的字节,mysql 就会使用双路排序,当任何需要的列(包含结果集列和 order by 的列)包含text、blob 列时,也会使用双路排序,(可以使用 subsstring()把这些列转化为可以单路排序的列)。
- 可以通过改变 max_length_for_sort_data 变量的值来影响mysql 选择的算法。因为单路排序要将排序的每一行创建固定的缓冲区,varchar 列的最大长度是 max_length_for_sort_data规定的值,而不是排序数据的实际大小(5.7.x 版本中对排序做了优化,分配排序缓冲时针对变长列可以根据数据实际占用的大小来分配内存)。
- 当 MySQl 不得不对 text、blob 列进行排序时,它只会使用前缀并忽略剩余的值,这是因为不得不分配固定大小的结构来容纳数据并且从外部存储中将前缀拷贝回结构中,可以使用max_sort_length 定义前缀应该是多大。
- mysql 并不能查看某个查询执行时内部使用的是哪种算法,如果增大了 max_length_for_sort_data 的值,并且磁盘使用率上升,cpu 使用率下降,Sort_merge_passes 的值比以前增加的更快,也许该强制排序使用单路排序算法。* 双路排序:读取行指针和 order by 列,对他们进行排序,然后扫描已经排序好的列表,按照列表中的值重新从列表中读取对应的数据输出。双路排序的开销可能会非常巨大,因为他会读取表两次,第二次读取会引发大量的随机 I/O,对于 MyISAM 涞说,这个代价尤其昂贵,MyISAM 表利用系统调用去提取每行的数据。
* 单路排序:读取查询需要的所有列,按照 order by 列对他们进行排序,然后扫描排序后的列表进行输出,它的效率更快一些,避免了第二次读取数据。并且把随机 I/O 变成了顺序 I/O,但是它会使用更多的内存空间,因为它把排序需要的所有列都一次性度的去出来保存在内存中了。
- 全局,会话,动态变量,整型值,单位为字节,取值范围4~8388608 字节,默认值为 1024 字节。