MySQL排序filesort慢查询order by优化
时间:2026-11-15 07:15 作者:emer 分类: MySQL
前言
ORDER BY 大数据量排序很慢,EXPLAIN 看到 Using filesort 就是在内存/磁盘额外排序。优化思路是让排序走索引,避免 filesort。本文讲解如何识别 filesort、联合索引配合排序、覆盖索引和限制。
操作步骤
1. EXPLAIN 看是否 filesort
EXPLAIN SELECT * FROM orders ORDER BY created_at DESC LIMIT 100;
Extra 出现 Using filesort。
2. 为排序列建联合索引
CREATE INDEX idx_created ON orders(created_at DESC);
3. 排序与过滤组合最左前缀
CREATE INDEX idx_status_created ON orders(status, created_at DESC);
WHERE status=? ORDER BY created_at 可走索引。
4. 只取需要列形成覆盖索引
SELECT id,created_at FROM orders ORDER BY created_at;
5. 调大排序缓冲区(辅助手段)
SET GLOBAL sort_buffer_size = 4*1024*1024;
6. 再次 EXPLAIN 确认 filesort 消失
EXPLAIN ...;
常见坑
- ORDER BY 列和 WHERE 条件列顺序不匹配,索引用不上。
- 排序方向 ASC/DESC 在旧版本联合索引里需一致。
- SELECT * 取大量列,无法形成覆盖索引。
- filesort 不一定真写磁盘,小结果集在内存。
- 索引过多写入变慢,只优化高频排序。
- 用函数包裹排序列导致索引失效。
- LIMIT 偏移很大仍需排序,分页要改方案。
总结
filesort 靠为 WHERE + ORDER BY 建匹配的联合索引消除,配合覆盖索引只取必要列。EXPLAIN 反复验证。sort_buffer_size 只是辅助,根因是索引;避免函数包裹排序列、SELECT *。
遇到问题加QQ23979811 协助处理