MySQL执行计划出现 Using filesort 是什么原因?如何进行优化?

AI 概述
1.Using filesort2.原因分析2.1 ORDER BY 未走索引2.2 JOIN 语句2.3 UNION 语句2.4 GROUP BY2.5 DISTINCT 语句2.6 临时表3.优化思路3.1 索引优化JOIN 优化配置优化4.总结 在对以一个 SQL 的执行计划进行分析时,我们会关注 Extra 这个属性,当这个属性的值是 Using filesort 时,就需要看下 SQL 是否需...
目录
文章目录隐藏
  1. 1.Using filesort
  2. 2.原因分析
  3. 3.优化思路
  4. 4.总结

在对以一个 SQL 的执行计划进行分析时,我们会关注 Extra 这个属性,当这个属性的值是 Using filesort 时,就需要看下 SQL 是否需要优化一下了。

1.Using filesort

比如下面的这个 SQL,排序字段上没有索引, 执行计划 Extra 就显示 Using filesort :

EXPLAIN SELECT * FROM test4 ORDER BY time_stamp;

Using filesort

也可以通过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 是指执行的 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 临时表

当查询需要创建临时表,比如上面的UNIONDISTINCTGROUP 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 是什么原因?如何进行优化?的文章就介绍到这了,更多相关内容请搜索码云笔记以前的文章或继续浏览下面的相关文章,希望大家以后多多支持码云笔记。

「点点赞赏,手留余香」

2

给作者打赏,鼓励TA抓紧创作!

微信微信 支付宝支付宝

还没有人赞赏,快来当第一个赞赏的人吧!

声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 admin@mybj123.com 进行投诉反馈,一经查实,立即处理!
重要:如软件存在付费、会员、充值等,均属软件开发者或所属公司行为,与本站无关,网友需自行判断
码云笔记 » MySQL执行计划出现 Using filesort 是什么原因?如何进行优化?

发表回复