ActiveRecord 查询优化

问题描述 投票:0回答:1

我有一个 ActiveRecord 查询,有时需要一分钟才能完成。我正在尝试找到优化它的方法,但不确定从哪里开始。

我有以下代码:

average_sql = 'TIMESTAMPDIFF(MINUTE, LEAST(notification_sent, responded_at), responded_at)'
UserPlacement.notified.responded.joins(:placement_campaign)
                     .merge(PlacementCampaign.not_instant)
                     .where('user_placements.created_at > ?', 3.months.ago).select(average_sql)

翻译成:

SELECT Timestampdiff(minute, Least(notification_sent, responded_at),
       responded_at)
FROM   `user_placements`
       INNER JOIN `placement_campaigns`
               ON `placement_campaigns`.`id` =
                  `user_placements`.`placement_campaign_id`
                  AND `placement_campaigns`.`deleted_at` IS NULL
WHERE  `user_placements`.`deleted_at` IS NULL
       AND ( `user_placements`.`notification_sent` IS NOT NULL )
       AND ( `user_placements`.`responded_at` IS NOT NULL )
       AND `placement_campaigns`.`deleted_at` IS NULL
       AND `placement_campaigns`.`instant` = 0
       AND ( user_placements.created_at > {{ 3.months.ago }} )
       AND `user_placements`.`user_id` = 1 

user_placements
表索引:

index_user_p_campaign_unique, ["placement_campaign_id", "user_id"]
fk__user_placements_tuser_id, ["user_id"]

placement_campaigns
指数:

index_placement_campaigns_on_placement_id, ["placement_id"]

我应该通过哪些步骤来分析和提高此查询的性能?

mysql activerecord query-optimization
1个回答
0
投票

索引:

placement_campaigns:  INDEX(deleted_at, instant, id)
user_placements:  INDEX(user_id, deleted_at, created_at)
user_placements:  INDEX(placement_campaign_id, user_id,
                        deleted_at, created_at)

JOIN 有点棘手,因为很难预测优化器将选择哪个表作为“第一个”。

这是我的索引食谱

“3个月前”可以拼写为

NOW() - INTERVAL 3 MONTH
© www.soinside.com 2019 - 2024. All rights reserved.