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

MySQL带日期过滤条件的分组查询执行过慢,如何优化

SQL查询性能优化方案

性能差异原因分析

  • 无WHERE条件时,查询仅需对subscription_subscription表的store_id字段分组统计,数据库可直接利用store_id上的索引完成聚合,无需回表扫描完整数据,因此执行速度极快。
  • 新增日期过滤条件后,无适配索引的情况下,数据库需要全表扫描100万行数据逐行判断end_date是否符合要求,再对符合条件的行做分组统计,额外的扫描和过滤操作导致耗时大幅上升。

优化方案

1. 新建联合覆盖索引(优先级最高)

给subscription_subscription表新建联合索引idx_sub_end_store,索引字段顺序为(end_date, store_id),建索引语句:

CREATE INDEX idx_sub_end_store ON subscription_subscription(end_date, store_id);

原理说明:该索引属于覆盖索引,包含了本次查询需要的所有字段:

  • 前缀end_date可快速定位所有满足CURRENT_DATE() <= end_date的行,跳过不符合要求的大量数据
  • 第二列store_id可直接用于分组统计,不需要回表查询主键数据,整个查询完全在索引中完成,性能可提升数倍到数十倍。

2. 避免字段隐式类型转换

确认end_date字段的类型为DATE类型,不要使用字符串、DATETIME/TIMESTAMP类型存储日期值,避免类型隐式转换导致索引失效。如果确实需要使用DATETIME类型,可以将过滤条件调整为CURRENT_TIMESTAMP() <= end_date,保证字段和过滤值的类型一致。

3. 预聚合方案(适配非强实时场景)

如果业务对统计数据的实时性要求不高(允许T+1或者小时级延迟),可以新增一张订阅统计汇总表,每天/每小时定时执行统计任务,提前把每个门店的有效订阅数计算好存入汇总表,查询时直接读取汇总表即可,耗时可降低到毫秒级。

4. 优化器适配

如果新建索引后优化器仍未选择该索引,可手动强制指定索引(以MySQL为例):

SELECT store_id, COUNT(*) AS sub_store
FROM subscription_subscription FORCE INDEX(idx_sub_end_store)
WHERE CURRENT_DATE() <= end_date
GROUP BY store_id
ORDER BY sub_store DESC

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 15:18:03