我有一个 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"]
我应该通过哪些步骤来分析和提高此查询的性能?
索引:
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