调大sort_buffer_size仅避免磁盘排序,不减少磁盘临时表;后者由tmp_table_size和max_heap_table_size控制,需通过Created_tmp_disk_tables/Created_tmp_tables比值及EXPLAIN的Using temporary判断。

调大 sort_buffer_size 不能避免磁盘临时表,它只影响排序阶段是否落盘;真正决定是否生成磁盘临时表的是 tmp_table_size 和 max_heap_table_size。
为什么改了 sort_buffer_size 却还在用磁盘临时表
常见误解是把“磁盘排序”和“磁盘临时表”混为一谈。MySQL 中这两者触发路径完全不同:
-
Sort_merge_passes上涨 → 表示排序过程被迫写磁盘临时文件(归并排序),和sort_buffer_size直接相关 -
Created_tmp_disk_tables上涨 → 表示 GROUP BY、DISTINCT、复杂 JOIN 等操作生成了磁盘临时表,由tmp_table_size和max_heap_table_size控制 - 即使
sort_buffer_size设到 4MB,只要查询需要建临时表且行数据总大小超tmp_table_size,照样下盘
sort_buffer_size 在 my.cnf 中的正确写法
必须放在 [mysqld] 段下,且不能与其它作用域参数(如 [client])冲突:
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
[mysqld] sort_buffer_size = 2M tmp_table_size = 64M max_heap_table_size = 64M
- 值推荐从
2M起步,万级行排序可试4M;超过8M很少必要,反而放大 OOM 风险 - 不要写成
2097152这类裸数字——MySQL 5.7+ 支持后缀K/M/G,更易读也不易错 - MySQL 8.0.22+ 禁止
SET GLOBAL sort_buffer_size,只能靠配置文件 + 重启生效 - 检查是否被多处定义覆盖:
mysqld --verbose --help | grep "sort_buffer_size"可看到最终加载位置
怎么确认磁盘临时表真被避免了
别只盯着 sort_buffer_size,得看三个状态变量联动变化:
- 执行慢查询前后,运行
SHOW GLOBAL STATUS LIKE 'Created_tmp%'; -
Created_tmp_disk_tables/Created_tmp_tables比值 0.1 就说明临时表频繁下盘 - 如果该比值高,优先调
tmp_table_size,不是sort_buffer_size - 同时查
EXPLAIN的Extra列:出现Using temporary就代表用了临时表,这时再看它是否落盘
真正容易被忽略的是协同参数——max_sort_length 和 read_rnd_buffer_size 会静默改变排序行为,哪怕 sort_buffer_size 调对了,它们设得太小,照样触发双路排序或额外磁盘 I/O。










