You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

十万条记录聚合查询耗时20-21秒,如何优化该SQL语句?

针对你遇到的10万条记录聚合查询耗时20+秒的问题,我给你几个具体的优化方向,都是实际场景中亲测有效的:

SQL查询优化方案

1. 替换前缀索引为覆盖联合索引

你当前创建的source(30)前缀索引只能帮优化器快速定位source非空的行,但查询还需要product_price和quantity来计算总和,这时候数据库不得不回表去主键索引里取这两个字段的值——这是导致查询缓慢的核心原因。

建议直接创建包含查询所需所有字段的覆盖索引:

ALTER TABLE `dbname`.`sheet` ADD INDEX `idx_source_price_qty` (`source`, `product_price`, `quantity`);

创建完成后,执行EXPLAIN查看执行计划,如果Extra列显示Using index,说明数据库直接从索引里获取所有需要的数据,完全不需要回表,这能把查询时间直接降到毫秒级。

2. 优化WHERE条件的过滤逻辑

如果source字段的空字符串('')占比很高,可以先确认是否能用source IS NOT NULL代替source !=''?不过要注意两者的区别:空字符串是'',NULL是无值,得根据你实际的数据情况选择。如果必须保留source !='',覆盖索引也能帮优化器快速过滤掉不符合条件的行。

3. 确认存储引擎为InnoDB

如果你的表目前用的是MyISAM,建议直接切换到InnoDB:

ALTER TABLE `dbname`.`sheet` ENGINE=InnoDB;

InnoDB的聚簇索引结构在处理聚合查询和覆盖索引时,效率远高于MyISAM,尤其是数据量较大的场景,切换后性能会有明显提升。

4. 用执行计划验证优化效果

每次调整后,一定要用EXPLAIN确认优化器的选择是否符合预期:

EXPLAIN SELECT source, sum(product_price*quantity) AS price FROM `sheet` WHERE source !='' GROUP BY source ORDER BY `price` DESC;

重点关注这几个字段:

  • type列:最好是range或ref(如果source有大量唯一值,可能会显示ref)
  • key列:是否用上了我们创建的idx_source_price_qty
  • Extra列:是否有Using index(覆盖索引生效的标志);如果ORDER BY的price是聚合后的结果,Using filesort可能无法避免,但只要覆盖索引生效,排序的开销会非常小。

5. 可选:预计算聚合结果(适合非实时查询)

如果你的数据不是需要实时更新的报表类查询,可以考虑每天定时预计算聚合结果,存到一个汇总表中:

-- 每天定时执行的预计算语句
INSERT INTO `sheet_summary` (source, total_price)
SELECT source, sum(product_price*quantity) AS total_price
FROM `sheet` WHERE source !='' GROUP BY source
ON DUPLICATE KEY UPDATE total_price = VALUES(total_price);

-- 查询时直接从汇总表取数据
SELECT source, total_price AS price FROM `sheet_summary` ORDER BY price DESC;

这种方式能把查询时间降到几乎为0,非常适合数据更新频率低的场景。

内容的提问来源于stack exchange,提问作者Sumit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:14:02