私のプロジェクトでは、Ruby ActiveRecord (ただし、Rails アプリケーションではありません) を使用しており、次の構造を使用しています。
class Customer < ::ActiveRecord::Base
has_and_belongs_to_many :categories
end
class Categories < ::ActiveRecord::Base
has_and_belongs_to_many :customers
end
アプリケーションの一部で、すべての顧客をロードして処理し、関連するカテゴリを熱心にロードしようとします ( ActiveRecord::IdentityMap.useブロック内):
Customer.includes(:categories).all
これで必要なことは実行されますが、結果のeager-loadクエリを見ると、次のようになっています:
SELECT "categories".*, "t0"."customer_id" AS ar_association_key_name_customer_id
FROM "categories" INNER JOIN "customers_categories" "t0"
ON "categories"."id" = "t0"."category_id" WHERE
((("t0"."customer_id" = 1) OR ("t0"."customer_id" = 2) OR ("t0"."customer_id" = 3) OR ... ))
すべての顧客をロードしていますが、結合テーブルでそれらをフィルタリングする必要はありません。いくつかのカテゴリしかありませんが、多くの顧客がいて、結果のクエリには何千もの不要な OR ステートメントがあります。
customer_id = X の形式で WHERE 条件を含めないように (ActiveRecord の方法で) クエリを簡素化する方法はありますか?