所以我有一个执行此操作的 rake 任务:
wine_club_memberships = WineClubMembership.pluck(:billing_info_id)
total_updated = BillingInfo.joins(:order).where(["orders.ordered_date < (CURRENT_DATE - 90) AND billing_infos.card_number IS NOT NULL AND billing_infos.card_number != '' AND billing_infos.id NOT IN (?)", wine_club_memberships]).update_all("card_number = ''")
log.error("Total records updated #{total_updated}")
问题是 BillingInfo 有 300,000 多条记录joins
,我想知道这一切是否与使用纯 SQL 相同。目前它的效率不是很高,因为我在语句中填充了大量的记录。where
update_all
WineClubMembership
有没有更有效的方法来做到这一点?尽管这是一个长而丑陋的陈述,但我认为它在大多数情况下会很有效,因为它几乎只需一两次访问数据库即可完成所有工作。但是,我周围的人认为必须有其他“Rails 方法”可以以更好的方式做到这一点,而不会影响生产网站的性能。
我确实看到“批量”进行搜索,但我不确定这是否会有所帮助。
更新
我正在使用 Postgres 9.1+。在我的 activerecord 搜索的旧(稍微简单一点)版本中,结果如下:
红宝石代码:
wine_club_memberships = WineClubMembership.pluck(:billing_info_id)
total_updated = BillingInfo.joins(:order).where(["orders.ordered_date < (CURRENT_DATE - 90) AND billing_infos.id NOT IN (?)", wine_club_memberships]).update_all("card_number = ''")
生成的 SQL:
SQL (127848.6ms) UPDATE "billing_infos" SET card_number = '' WHERE "billing_infos"."id" IN (SELECT "billing_infos"."id" FROM "billing_infos" INNER JOIN "orders" ON "orders"."id" = "billing_infos"."order_id" WHERE (orders.ordered_date < (CURRENT_DATE - 90) AND billing_infos.id NOT IN (423908,390663,387323,402393,383446,416114,391009,456371,384305,386681,384382,384418, ...)))