目录

【MySQL】Order By执行流程

sort_buffer

MySQL会给每个连接线程分配一块内存,称为sort_bufferorder by的所有排序算法,都需要依靠这块内存来完成。

全字段排序

假设有一条查询语句:

1
select city, name, age from t where city='杭州' order by name limit 1000;

其中,字段city上有普通索引。

通常情况下,order by的执行流程为:

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

  2. 从索引city找到满足条件的第一行记录,获取主键id

  3. 从主键索引找到整行,取出namecityage三个字段,放入sort buffer

  4. 在索引city中继续取下一个记录。

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

  6. 取前1000行返回。

rowid 排序

如果单行数据太大,MySQL会采用rowid排序。

参数max_length_for_sort_data用来控制排序数据的长度。如果单行数据长度超过该值,MySQL就认为单行太大,转而使用rowid排序。

还是同样的查询语句:

1
select city, name, age from t where city='杭州' order by name limit 1000;

同样,字段city上有普通索引。rowid排序的流程为:

  1. 初始化sort_buffer,确定name, id两个字段。

  2. 从索引city获取第一个满足要求的记录,获取主键id

  3. 从主键索引取出整行,取nameid两个字段,存入sort_buffer

  4. 从索引city取下一个记录。

  5. sort_buffername排序。

  6. 取前1000行,按照id的值回原表取citynameage三个字段返回。

sort_buffer_size

排序操作可能在内存中完成,也可能使用外部排序。这取决于排序所需内存,和参数sort_buffer_size

参数sort_buffer_size代表着sort_buffer的大小,如果待排序数据量小于该参数,排序就在内存中完成,否则就在临时文件中完成。

外部排序一般使用归并排序算法。

排序算法比较

如果内存够大,MySQL会优先选择全字段排序,因为rowid排序会多次回表,从而导致多次读磁盘。