MySQL执行带sum()聚合函数的子查询超时如何排查解决
超时原因
- 核心问题是使用了性能极差的关联子查询写法:子查询依赖外层查询传入的
a.name值,执行逻辑是外层每生成一个name分组结果,就触发一次子查询对trx表做全表扫描匹配。如果trx表数据量较大、name去重后的值较多,总扫描行数会达到「表总行数 × 去重后name的数量」,计算开销陡增,直接导致查询超时。 - 无匹配索引进一步拖慢速度:如果trx表没有针对
name、time、amount字段建联合索引,不管是外层的group by分组,还是子查询的条件过滤、sum计算,都要走全表扫描,磁盘IO开销极高,执行时间会被进一步拉长。 - 写法存在冗余:需求本质是按name分组统计2022-06-08之后的amount总和,不需要做自表关联+嵌套子查询,多余的表访问会产生不必要的性能损耗。
优化方法
直接用条件聚合改写SQL,仅需扫描一次trx表就能得到结果,性能会有量级提升:
SELECT name, SUM(CASE WHEN time > '2022-06-08' THEN amount ELSE 0 END) AS Sum FROM trx GROUP BY name;
如果表数据量很大,可以额外创建联合索引,让整个查询直接走索引完成,不需要回表取数,速度会更快:
CREATE INDEX idx_trx_name_time_amount ON trx(name, time, amount);
内容的提问来源于stack exchange,提问作者user19301640
相关产品推荐
相关产品推荐

