だから私はこれを行うレーキタスクを持っています:
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 件以上のレコードがあるということです。これらすべてが、純粋な SQL を使用するのとまったく同じであるかどうか疑問に思っていますjoins
。ステートメントに詰め込むレコードの膨大な配列があるため、現在はあまり効率的ではありません。where
update_all
WineClubMembership
これを行うより効率的な方法はありますか?これは長く醜いステートメントですが、データベースへの 1 回か 2 回のヒットでほぼすべてのことを実行できるため、ほとんどの場合効率的であると考えていました。しかし、私の周りの人々は、実稼働 Web サイトのパフォーマンスに影響を与えずに、より良い方法でこれを行うことができる他の "Rails メソッド" があるに違いないと考えています。
「バッチ」で検索を行っているのを見ましたが、それが役立つかどうかはわかりません。
アップデート
Postgres 9.1+ を使用しています。私のアクティブレコード検索の古い(少し単純な)バージョンでは、これが出てきました:
ルビーコード:
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, ...)))