【MySQL】Order By执行流程
sort_buffer
MySQL会给每个连接线程分配一块内存,称为sort_buffer。order by的所有排序算法,都需要依靠这块内存来完成。
全字段排序
假设有一条查询语句:
|
|
其中,字段city上有普通索引。
通常情况下,order by的执行流程为:
-
初始化
sort_buffer,确定name、city、age三个字段。 -
从索引
city找到满足条件的第一行记录,获取主键id。 -
从主键索引找到整行,取出
name、city、age三个字段,放入sort buffer。 -
在索引
city中继续取下一个记录。 -
对
sort_buffer中的数据按照字段name做快速排序。 -
取前
1000行返回。
rowid 排序
如果单行数据太大,MySQL会采用rowid排序。
参数max_length_for_sort_data用来控制排序数据的长度。如果单行数据长度超过该值,MySQL就认为单行太大,转而使用rowid排序。
还是同样的查询语句:
|
|
同样,字段city上有普通索引。rowid排序的流程为:
-
初始化
sort_buffer,确定name, id两个字段。 -
从索引
city获取第一个满足要求的记录,获取主键id。 -
从主键索引取出整行,取
name、id两个字段,存入sort_buffer。 -
从索引
city取下一个记录。 -
对
sort_buffer按name排序。 -
取前
1000行,按照id的值回原表取city、name和age三个字段返回。
sort_buffer_size
排序操作可能在内存中完成,也可能使用外部排序。这取决于排序所需内存,和参数sort_buffer_size。
参数sort_buffer_size代表着sort_buffer的大小,如果待排序数据量小于该参数,排序就在内存中完成,否则就在临时文件中完成。
外部排序一般使用归并排序算法。
排序算法比较
如果内存够大,MySQL会优先选择全字段排序,因为rowid排序会多次回表,从而导致多次读磁盘。