using filesort表示mysql无法利用索引有序性,必须额外排序;它出现在explain的extra列即说明触发排序,无论内存或磁盘执行,核心原因是where与order by未严格匹配索引最左前缀、方向不一致、含函数或非覆盖字段。

看 Extra 字段里有没有 Using filesort
MySQL 执行计划(EXPLAIN 输出)中,只要 Extra 列出现 Using filesort,就明确表示该查询触发了文件排序——哪怕数据量很小、内存足够,只要优化器决定走这个路径,就会标记它。
注意:这不是“磁盘写文件”的字面意思,而是指 MySQL 无法利用索引完成有序输出,必须额外做一趟排序操作(可能在内存,也可能落磁盘)。所以不能靠观察 tmp_table 或磁盘 I/O 来反推。
-
Using filesort出现在EXPLAIN的某一行,说明对应表的扫描结果需要排序;如果是多表 JOIN,要逐行看哪张表触发了它 - 即使
ORDER BY字段上有索引,也可能出现Using filesort——比如索引顺序和ORDER BY不一致(INDEX(a,b)但ORDER BY b,a),或用了函数/表达式(ORDER BY UPPER(name)) -
Using index和Using filesort可以共存,说明走了覆盖索引,但排序仍需额外步骤
为什么 type=ALL 或 type=index 时更容易发生文件排序
全表扫描(type=ALL)或全索引扫描(type=index)意味着 MySQL 拿到的数据天然无序,如果还要按某字段排序,基本逃不开 Using filesort。这时候优化重点不是“怎么避免标记”,而是“能不能加合适的索引让 type 提升为 range 或 ref,同时满足排序需求”。
- 例如
SELECT * FROM t WHERE status=1 ORDER BY create_time,若只有status单列索引,执行计划大概率是type=ref+Using filesort;改成联合索引(status, create_time)就能消除 -
type=index本身已按索引顺序读取,但如果ORDER BY方向不匹配(如索引是ASC,而写ORDER BY x DESC),仍会触发Using filesort - 复合条件 + 多字段排序时,索引字段顺序必须严格匹配
WHERE前缀 +ORDER BY全部字段,中间不能跳过
sort_buffer_size 不够时,Using filesort 会真的写磁盘
有 Using filesort 不代表一定慢,但一旦 sort_buffer_size 不足以容纳全部待排序行,MySQL 就会拆成多个块分别排序,再归并——这时会产生临时文件,I/O 开销明显上升。可通过 SHOW STATUS LIKE 'Sort_%' 观察:
-
Sort_merge_passes> 0 表示发生了归并排序,说明内存不够 -
Sort_rows是总排序行数,结合查询返回行数可判断是否过度排序(比如LIMIT 10却排了 10 万行) - 调大
sort_buffer_size仅对单个连接生效,不能全局乱设;真正有效的是减少参与排序的数据量(加更严格的WHERE)或用索引覆盖
常见误判:把 Using temporary 当成文件排序
Using temporary 表示创建了内部临时表(常用于 GROUP BY、DISTINCT 或某些 JOIN 场景),它和 Using filesort 是两个独立动作。两者可能同时出现,但没有因果关系——比如 GROUP BY a ORDER BY b 可能既需要临时表聚合,又需要额外排序。
- 不要看到
Using temporary就去查排序问题;先确认Extra是否含Using filesort -
Using temporary本身也可能落磁盘(tmp_table_size/max_heap_table_size不足),但这属于临时表溢出,和排序逻辑无关 - 5.7+ 版本中,如果
ORDER BY能被索引满足,即使有GROUP BY,也未必出现Using filesort;得具体看索引设计
真正关键的信号始终只有一个:Extra 列里的 Using filesort。其他指标都是辅助定位原因,而不是替代判断依据。











