MySQL执行计划出现 Using filesort 是什么原因?如何进行优化?
在对以一个 SQL 的执行计划进行分析时,我们会关注 Extra 这个属性,当这个属性的值是 Using filesort 时,就需要看下 SQL 是否需要优化一下了。
1.Using filesort
比如下面的这个 SQL,排序字段上没有索引, 执行计划 Extra 就显示 Using filesort :
EXPLAIN SELECT * FROM test4 ORDER BY time_stamp;
![]()
也可以通过FORMAT=JSON获取更详细的信息:
EXPLAIN FORMAT=JSON SELECT * FROM employees ORDER BY first_name;
结果如下:
{
"query_block": {
"select_id": 1,
"cost_info": {
"query_cost": "1034355.60"
},
"ordering_operation": {
"using_filesort": true,
"cost_info": {
"sort_cost": "857663.00"
},
"table": {
"table_name": "test4",
"access_type": "ALL",
"rows_examined_per_scan": 857663,
"rows_produced_per_join": 857663,
"filtered": "100.00",
"cost_info": {
"read_cost": "5160.00",
"eval_cost": "171532.60",
"prefix_cost": "176692.60",
"data_read_per_join": "65M"
},
"used_columns": [
"id",
"a",
"b",
"date",
"date_time",
"time_stamp"
]
}
}
}
}
Using filesort 是指执行的 SQL 无法使用索引进行排序,需要在内存或磁盘上进行排序。如下图:

所以 Using filesort 不是一定会使用磁盘排序。
那 Using filesort 对性能有哪些影响呢?
- 排序操作需要大量 CPU,CPU 消耗很大;
- 如果在内存中排序,排序操作会消耗很大内存;
- 当数据无法在内存中完成排序时,就会用到磁盘临时文件,消耗磁盘 I/O。
由于 CPU、内存或磁盘的消耗,会直接导致 SQL 性能下降,执行时间长。
2.原因分析
2.1 ORDER BY 未走索引
这是最常见的原因,主要包括以下几种情况:
- ORDER BY 字段未加索引;
- ORDER BY 语句中字段排序顺序跟索引顺序不一致;
- 有复合索引,但 ORDER BY 语句中的列不符合最左前缀原则;
- ORDER BY 语句中使用了表达式或函数。
上面这些情况都可能走 filesort。
2.2 JOIN 语句
SELECT * FROM t1 JOIN t2 ON t1.c1=t2.c1 order by t2.c2;
MySQL 会选择结果集较小的表作为驱动表,比如上面的 SQL,两张表使用 c1 这个字段进行 JOIN,如果选择了 t1 做为驱动表,但是使用 t2 的字段 c2 进行排序,那排序操作就会走不上索引。
2.3 UNION 语句
EXPLAIN SELECT id,a,b FROM test4 UNION SELECT * FROM test5 ORDER BY a;
在 union 语句中,如果对结果集进行排序,也有可能会走 filesort。
2.4 GROUP BY
SELECT age,COUNT(age) ca FROM db_staff GROUP BY age;
上面是一个分组的 SQL,在 MySQL 8.0 以前,GROUP BY 默认是会对分组字段做排序的,即使 sql 中没写 ORDER BY,也会排序。如果分组字段未加索引,很容易走 filesort。
如果想要 sql 语句不排序,可以在 sql 尾部加 order by null。
2.5 DISTINCT 语句
EXPLAIN SELECT DISTINCT b FROM test5 ORDER BY b;
如果在 DISTINCT 语句中使用ORDER BY,可能会走filesort。
2.6 临时表
当查询需要创建临时表,比如上面的UNION、DISTINCT和GROUP BY,如果临时表结果集需要排序,则可能使用filesort。
3.优化思路
3.1 索引优化
如果 ORDER BY 字段没能走索引,可以考虑进行优化:
- ORDER BY 只有一个字段,则为该字段增加索引;
- ORDER BY 有多个字段,可以考虑复合索引。比如下面的示例:
CREATE INDEX idx_a_b ON orders(a, b); EXPLAIN SELECT * FROM test4 WHERE a = 'testa' ORDER BY b;
- 排除可能使索引失效的情况,比如函数或表达式、ORDER BY 和索引顺序不一致;
- 没有必要排序的场景,可以不排序,比如使用 ORDER BY NULL 语句。
JOIN 优化
确保 ORDER BY 子句的字段是驱动表上的索引字段,并且符合最左前缀原则,必要时可以强制使用索引 FORCE INDEX。
配置优化
增大 sort_buffer_size 配置,避免走磁盘排序。不过一定要注意,sort buffer 是会话私有的,高并发场景下,可能导致数据库内存升高。
4.总结
当执行计划的 Extra 属性出现 Using filesort 时,大概率我们的 SQL 需要优化了。可能查看 SQL 属于那种情况,针对性地进行优化。
以上关于MySQL执行计划出现 Using filesort 是什么原因?如何进行优化?的文章就介绍到这了,更多相关内容请搜索码云笔记以前的文章或继续浏览下面的相关文章,希望大家以后多多支持码云笔记。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 admin@mybj123.com 进行投诉反馈,一经查实,立即处理!
重要:如软件存在付费、会员、充值等,均属软件开发者或所属公司行为,与本站无关,网友需自行判断
码云笔记 » MySQL执行计划出现 Using filesort 是什么原因?如何进行优化?

微信
支付宝