using filesort说明mysql未利用索引排序,需额外内存或磁盘排序,导致cpu和i/o开销陡增、万级数据即卡顿;应通过explain紧盯extra(含using filesort则未走索引排序)和key(为null或未显示目标索引名则索引未被选用),联合索引须按等值条件字段→排序字段严格连续且方向一致构建,如where status=1 and type='vip' order by created_at desc应建index (status, type, created_at desc),并注意版本兼容性、隐式转换及join中被驱动表排序失效等硬伤。

看到 Using filesort 就说明 MySQL 没法靠索引直接返回排好序的结果,必须额外做一次排序——无论是在内存还是磁盘上,CPU 和 I/O 开销都会明显上涨,数据量一过万就容易卡顿。
先确认是不是真没走索引排序
别凭感觉,直接用 EXPLAIN 看执行计划,重点盯两列:
- Extra 出现 Using filesort → 排序没走索引
- key 是 NULL 或没显示你建的索引名 → 索引压根没被选中
注意:type = index 不代表排序优化成功,如果 Extra 还有 Using where 或没出现 Using index,说明仍要回表,排序优势已经打折扣。
Java开发手册规约集合,基于阿里巴巴Java开发手册(嵩山版)。 涵盖7大维度:编程规约、异常日志、单元测试、安全规约、MySQL数据库、工程结构、设计规约。 当用户需要:(1) 编写或审查Java代码 (2) 检查命名/代码规范 (3) 处理异常和日志 (4) 编写单元测试 (5) 安全编码 (6) 数据库设...
联合索引怎么建才真正管用
核心逻辑是:等值条件字段放最左,排序字段紧贴其后,方向严格一致。
- 查询是
WHERE status = 1 AND type = 'vip' ORDER BY created_at DESC→ 建索引INDEX (status, type, created_at DESC) - 如果有范围条件,比如
WHERE status = 1 AND created_at > '2026-01-01',那ORDER BY只能跟在created_at后面的字段才有效 - MySQL 8.0+ 支持混合升降序(如
(status, created_at DESC)),但 5.7 及更早版本只认全 ASC 或全 DESC,否则可能失效
容易被忽略的硬伤
建了索引还是出 Using filesort,常见原因有:
- WHERE 和 ORDER BY 字段不在同一个联合索引里(比如只在
status上建单列索引,却写WHERE status = 1 ORDER BY created_at) - 字段隐式转换:索引是
VARCHAR(255),但查询用了VARCHAR(100)表达式,或字符集不一致(utf8mb4vsutf8) - JOIN 后的 ORDER BY 用的是被驱动表字段,而索引建在驱动表上——这种场景下,即使单表索引再好也没用
覆盖查询字段减少回表
在确保排序走索引的前提下,可以把常用 SELECT 字段加到索引末尾,构成覆盖索引:
- 比如只查
id, name, created_at,可建INDEX (status, created_at DESC, id, name) - TEXT/BLOB 类型字段不能建索引,覆盖索引里得排除它们
- 别盲目塞
SELECT *所有字段进索引——空间膨胀快、写入变慢,收益反而下降










