“order by”是怎么工作的?

117 阅读2分钟

全字段排序

Extra 这个字段中“using filesort”表示的就是需要排序,Mysql会给每个线程分配一块内存用于排序,称为 sort_buffer。

在一个表上建立普通索引(city),查询语句流程如下。

1.初始化sort_buffer,确定放入name、city、age这三个字段。

2.从索引city找到第一个满足city = 'xxx' 条件的主键id。

3.到主键id索引取出整行,取出name、city、age三个字段的值,存入sort_buffer中。

4.从索引city去下个记录的主键id。

5.重复步骤3、4知道city的值不满足条件位置,对应的主键id。

6.对sort_buffer中的数据按照字段name做快速排序。

7.按照排序结果取1000行返回给客户端。

我们把这个排序过程,称为全字段排序。排序可能需要使用外部排序,这取决于排序所需的内存和参数sort_buffer_size。

sort_buffer_size,就是mysql为排序开辟的内存(sort_buffer)的大小。如果要排序的数据量小于sort_buffer_size,排序就在内存中完成。但如果排序的数据量太大,内存放不下,则不得不利用磁盘临时文件辅助排序。

这个方法是通过查看OPTIMIZER_TRACE的结果来确认,你可以从number_of_tmp_files中看到使用了临时文件。number_of_tmp_files表示的是,排序过程中使用的临时文件数。mysql把每一份单独排序存到这些临时文件中,然后把这12个有序文件在合并成一个有序的大文件。

rowid 排序

上面的算法过程里面,指对原表的数据读了一遍,剩下的操作都是在sort_buffer和临时文件中执行的。但是这个算法有一个问题,就是如果查询要返回的字段很多的话,那么sort_buffer里面要放的字段数量太多,这样内存能够同时放下的行数很少,要分成很多临时文件,排序性能会很差。

如果Mysql认为排序的单行长度太大了会怎么做?

set max_length_for_sort_data = 16

max_length_for_sort_data,是mysql中专门控制用于排序的行数据的长度的一个参数,他的意思是,如果单行的长度超多这个值,Mysql就认为单行太大,要换一个算法。