IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

Filesort过程

MySQLOPS 数据库与运维自动化技术分享 2012-08-20 23:32:00 累计浏览 2,428 次
本机暂存
看mysql源码的收获
•为优化提供理论依据
•为优化提供方向
•学习解决问题的算法和思路

filesort algorithm

  • 读取所有需要排序的数据
  • 每行数据
  •     算法1(original):存储排序key和行指针
  •     算法2(modified):存储排序key和select中的字段
  • 每次排序sort_buffer_size能容纳的行数,排序结果写入IO_CACHE对象(不妨称为IO1),本次排序结果的位置信息写入另一个IO_CACHE对象(不妨称为IO2);
  • IO_CACHE超过64k时写入临时文件
  • 当order by有limit n时,只需要把前n条排序结果写入IO_CACHE;
  • 排序KEY长度<=20且排序KEY数量在一千和十万之间时使用radixsort,否则使用quicksort
  • Merge buffer
  • 读取排序结果(算法2直接从临时文件读取结果;算法1从临时文件读取行指针,再从表中读取数据)

merge buffer

原图已失效

filesort algorithm选择

select bgid from bigt order by bgname;

Create Table: CREATE TABLE `bigt` (

`bgid` int(10) unsigned NOT NULL AUTO_INCREMENT,

`bgname` varchar(100) DEFAULT NULL,

`status` tinyint(4) DEFAULT ’0′,

PRIMARY KEY (`bgid`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1

bgid(4字节)、bgname(102字节)、(null_fields+7)/8=1

其中null_fields是1,bgname是可以为空的字段

length=4+102+1=107

sort_length=101(bgname长度)

  • 满足下两个条件之一时选择original算法
  •       有text或者blob字段
  •       length+sortlength > max_length_for_sort_data
  • 否则选择modified算法
  • 本例选择了modified算法
  •       没有text和blob字段
  •       length+sortlength=208
  •       max_length_for_sort_data=1024

Sort buffer内存使用

  • keys= sort_buff_size/(rec_length+sizeof(char*))
  • rec_length=length+sortlength
  • 本例中
  •     rec_length=208
  •     sizeof(char*)=4
  •     sort_buff_size=2097116
  •     keys=9892
  •     即能在内存中一次排序的key为9892个

倒序的实现

  • 不是在比较KEY值大小时实现
  •     发现正序、倒序,在比较KEY值大小的函数中没有区别对待
  •     差点以为把整个排序过程看错了
  • 是在向排序区写入KEY值时实现
  •     在跟踪字符类型倒序倒序时
  •     make_sortkey中对每个字节取反
  •     这样后续的正序排序就相当于倒序排序

正序排序Merge buffer示例

  • 实际mysql源码中是每7个buffer进行合并
  • 本例做了简化,只对5个buffer进行合并
  • 所谓buffer是一次排序结果,保存在临时文件(IO_CACHE)中
  • 5个buffer就是临时文件中的五个段,每段保存一次排序的结果
  • Merge buffer的算法是heapsort实现的mergesort
  • 首先每个段取第一个排序key,加入heap
  • 加入时保证heap的排序
原图已失效
原图已失效
原图已失效
原图已失效
原图已失效
原图已失效
原图已失效
原图已失效

Merge buffer总结

•MySQL源码中,周而复始进行合并
•每次合并7个buffer,直到全部合并
•合并时仍然使用sort buffer内存
•最后一次合并时不再向排序结果中写入排序KEY,只写需要的字段值
•各buffer自己的最小值,在一起再取最小值,就是所有buffer数据的最小值
•除去当前取得的最小值,再算当前buffer最小值的最小值,以此类推,得到排序的所有buffer数据
•用heapsort实现的mergesort

为什么用heapsort?

• 每次合并若干buffer时,不能拿到所有buffer的全部数据
•对能取到sort buffer内的所有数据完全排序是没意义的
•以顺序排序举例,这些数据中,只有当前各buffer的最小值中的最小值能够保证是所有buffer中最小的值,依次得到这个最小值,则得到完全排序的所有数据
•heapsort也恰好是不完全排序,只保证root是最小的

运维上的思考

•计算一个SQL是否能在内存中完成排序
•计算一个SQL使用哪种filesort算法
•Merge buffer的代价?
•filesort旧算法与新算法资源消耗的评估?

同分类推荐文章

  1. 使用deepseek进行Oracle恢复,引起重大故障 (2026-06-22 10:56:00)
  2. 接手一个只差临门一脚的数据库恢复 (2026-06-18 00:13:09)
  3. 我做了一个 AI 版的 StarRocks 升级风险扫描工具,直接帮我定位到一个风险 (2026-06-15 01:00:00)

查看更多 数据库 文章 →

建议继续学习

  1. 用Hyer来进行网站的抓取 (累计阅读 158,252)
  2. MySQL数据库在实际应用一些方面的介绍 (累计阅读 36,400)
  3. WordPress插件开发 -- 在插件使用数据库存储数据 (累计阅读 29,164)
  4. Mysql监控指南 (累计阅读 21,352)
  5. 由浅入深探究mysql索引结构原理、性能分析与优化 (累计阅读 16,523)
  6. 在Apache2.2.XX下安装Mod-myvhost模块 (累计阅读 13,058)
  7. 15个最好的免费开源电子商务平台 (累计阅读 12,541)
  8. 浅谈MySQL索引背后的数据结构及算法 (累计阅读 11,909)
  9. 整理了一份招PHP高级工程师的面试题 (累计阅读 11,709)
  10. 腾讯-1亿个数据取前1万大的整数-题解答 (累计阅读 10,074)