应先确认是否真有using filesort:用explain查看extra列,若出现该提示且索引未覆盖排序字段(如字段超长、类型为text或缺少复合索引),才需调整;否则调大纯属浪费内存。

sort_buffer_size 不是越大越好,设高了反而容易 OOM;它只在真正需要排序时按连接分配,且不复用——调它前先确认是不是真有 Using filesort。
怎么判断要不要调 sort_buffer_size
MySQL 只在无法用索引完成排序时才动这个 buffer,比如 ORDER BY 字段没索引、或索引不覆盖、或字段太长(如 VARCHAR(2000))导致索引失效。这时候执行计划的 Extra 列会出现 Using filesort,慢查询日志里也可能先看到它,然后才是 Out of sort memory 报错。
- 用
EXPLAIN SELECT ... ORDER BY ...看Extra是否含Using filesort - 如果
type是index或range,但仍有Using filesort,说明索引没覆盖排序需求 - 如果字段类型是
TEXT或超长VARCHAR,即使建了索引,InnoDB 也可能因长度限制退化为 filesort - 没出现
Using filesort却调大sort_buffer_size,纯属浪费内存
怎么安全地调 sort_buffer_size
它是会话级变量,每个连接独占一份,不能全局硬塞。设成 256MB 或 1GB 是常见翻车点——100 个并发连接就吃掉 25GB 内存,还没算其他 buffer。
- 默认值通常是
262144(256KB),单位是字节,不是 MB - 线上建议用
SET SESSION sort_buffer_size = 4194304(即 4MB)临时设置,仅对当前查询生效 - 查当前值:运行
SHOW VARIABLES LIKE 'sort_buffer_size' - 避免写进
my.cnf全局配置,除非你精确算过:max_connections × sort_buffer_size ≤ 总内存 × 10% - MySQL 8.0+ 支持动态改全局:
SET GLOBAL sort_buffer_size = 4194304,但重启后失效,且需 SUPER 权限
sort_buffer_size 和 read_rnd_buffer_size 到底谁该动
这两个常被混用,但职责分明:sort_buffer_size 管排序阶段内存,read_rnd_buffer_size 管排序完回表取数据时的随机读缓冲。只有当执行计划同时出现 Using filesort 和 Using where(或 Using index condition),且排序字段不在索引中时,后者才可能成为瓶颈。
- 先看
EXPLAIN输出:有Using filesort就优先调sort_buffer_size;若还有Using temporary,再考虑两者都检查 -
read_rnd_buffer_size默认通常比sort_buffer_size小(比如 256KB vs 2MB),也按连接分配,同样禁不住无脑拉高 - 如果查询带
ORDER BY ... LIMIT且非覆盖索引,回表量大,read_rnd_buffer_size才值得微调 - 两者都不会复用,一次查询结束就释放,不存在“缓存效果”
真正卡顿或爆内存时,90% 的情况不是 buffer 太小,而是索引没建对——比如 ORDER BY status, created_at 就该建 INDEX(status, created_at),而不是把 sort_buffer_size 拉到 32MB。buffer 是兜底手段,索引才是正解。











