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

ActiveRecord查询优化:如何分析并提升慢查询性能?

分析并优化查询性能的步骤

1. 用执行计划定位瓶颈

在目标SQL前添加EXPLAIN关键字执行,重点关注以下字段:

  • type:如果显示ALL说明存在全表扫描,是核心优化点;
  • key:查看实际命中的索引,若为NULL则代表未用到有效索引;
  • rows:预估扫描的行数,数值越大意味着查询要处理的数据量越多;
  • Extra:如果出现Using filesort或Using temporary,说明存在额外排序/临时表开销,需调整逻辑。

2. 针对性优化索引

现有索引无法覆盖查询的核心过滤条件,建议新增以下复合索引:

针对user_placements表

查询的核心过滤条件是user_id = 1(等值匹配)、created_at > 三个月前(范围匹配),再加上deleted_at、notification_sent、responded_at的非空过滤,创建复合索引:

CREATE INDEX idx_user_placements_user_created ON user_placements (user_id, created_at, deleted_at, notification_sent, responded_at);

理由:等值条件放在最前面,接着是范围条件,最后补充其他过滤字段,让数据库能快速定位到目标行,避免全表扫描。

针对placement_campaigns表

查询需要过滤instant = 0、deleted_at IS NULL,同时要关联id字段,创建索引:

CREATE INDEX idx_placement_campaigns_instant_deleted ON placement_campaigns (instant, deleted_at, id);

这样JOIN操作时能快速匹配符合条件的活动记录,避免扫描整个表。

3. 简化实时计算逻辑

查询中的TIMESTAMPDIFF+LEAST是实时计算,数据量大时会增加CPU开销:

  • 在user_placements表新增response_delay_minutes字段(INT类型);
  • 通过数据库触发器或ActiveRecord的before_save/before_update回调,在notification_sent或responded_at更新时自动计算并填充该字段;
  • 后续查询直接SELECT response_delay_minutes,省去实时计算的开销。

4. 减少无效数据扫描

  • 清理软删除数据:如果两张表中有大量deleted_at IS NOT NULL的软删除数据,定期归档或清理,避免查询时过滤无效数据;
  • 缩小时间范围:如果业务允许,把查询的时间范围从三个月缩小到更短的周期,大幅减少扫描行数。

5. 预聚合统计数据

如果该查询是统计类需求(不需要实时数据):

  • 建立统计数据表(如user_response_stats),包含user_id、average_delay、stat_date等字段;
  • 用定时任务(如Sidekiq、数据库事件)每天/每小时预计算平均值并写入统计表;
  • 查询时直接从统计表取数,无需每次扫描大量原始数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 22:44:59