mysql/sql/filesort.cc的理解

"filesort"接收要排序的table和要排序的fields,根据sortbuff_size的设定,申请尽量大的一个sortbuff用来存放即将被排序的keys。
然后进入"find_all_keys"函数,因为sortbuff大小有限,主要排序思路如find_all_keys的注释:
while (get_next_sortkey())
{
if (no free space in sort_keys buffers)
{
sort sort_keys buffer;
dump sorted sequence to 'tempfile'; //IO_CACHE类型的文件,负责保存各个子序列排序后的结果
dump BUFFPEK describing sequence location into 'buffpek_pointers'; //IO_CACHE类型的文件,负责保存子序列在tempfile中子序列buf的开始位置。
}
put sort key into 'sort_keys';
}
if (sort_keys has some elements && dumped at least once)
sort-dump-dump as above;
else
don't sort, leave sort_keys array to be sorted by caller.

个人理解:find_all_keys中的具体实现对于select的sql语句中有无limit N,回去别对待。因为limit我们只要求出最小(大)的N个就好排序算法可以使用堆排序的变形求最小的N个???这个看不懂,不确定。。但是如果没有limit N的话,它是对table中的每一条记录都遍历一遍看是否符合要求。


在对各个子序列排序后,filesort调用"merge_many_buff"和"merge_index"将各个小的有序子序列,merge成个数小于一个"上限"的子序列,结果存放在outfile中,BUFFPEK依然存放在buffpekfile中。merge_many_buffh和merge_index都会调用merge_buff。
在merge_many_buff中会多次调用的具体操作流程是:

while(*maxbuffer >= MERGEBUFF2) { //让buff的数据减少到一定程度
merge from_file into to_file
then from_file <=> to_file //交换指针。
}

将每个子序列merge之后就是我们最后想要的sort的序列。

 

posted @ 2012-06-23 21:18  Jack204  阅读(416)  评论(0编辑  收藏  举报