has_one 関連付けが設定されたモデルがあります。
class User
has_one :shirt
class Shirt
belongs_to :user
現時点では.includes(:shirt)
、ユーザーの限られた配列を取得するときに追加でき、期待どおりに 2 つの SQL クエリを実行します。
私たちにとっての問題は、ページをロードするためのクエリがこれを行っていることです。
SELECT "shirt".* FROM "shirts" WHERE "shirt"."user_id" IN (2147521, 2147522 ... )
たとえば、50 人のユーザーとシャツを取得する場合、これはあまりパフォーマンスが高くありません。私たちのユーザーとシャツのテーブルは大きいです。次のようにして、Rails に強制的に INNER JOIN を使用させることで、速度が大幅に向上することに気付きました。
User.where( ... ).joins(:shirts).includes(:shirts).limit(50)
残念ながら、これはシャツを持っているユーザーのみを返します。関連するシャツを持っているかどうかに関係なく、限られたユーザーの配列を返すことができる必要があります。
デフォルトの2クエリ方式の代わりにLEFT OUTER JOINを使用してRailsに関連付けられたオブジェクトを熱心にロードさせる方法はありますか?
編集
where
関連付けられたオブジェクトの値が null かどうかにかかわらず true を返す句を追加します。関連付けられたオブジェクトがなくても、少なくとも Postgres では問題ないようです。
User.where( ... ).includes(:shirt).where("shirts.created_at IS NULL OR shirts.created_at IS NOT NULL")
これで問題は解決しますが、理想的とは言えません。デフォルトの 2 クエリ アプローチの代わりに LEFT OUTER JOIN を使用する方法はありませんか?