我们有一个设置了 has_one 关联的模型:
class User
has_one :shirt
class Shirt
belongs_to :user
目前我们可以.includes(:shirt)
在检索有限的用户数组时添加,它将按预期执行两个 SQL 查询。
我们的问题是加载页面的查询是这样做的:
SELECT "shirt".* FROM "shirts" WHERE "shirt"."user_id" IN (2147521, 2147522 ... )
例如,在检索 50 个用户和衬衫时,这对我们来说性能不是很好。我们的用户和衬衫表很大。我们注意到通过强制 Rails 使用 INNER JOIN 来代替执行以下操作可以大大提高速度:
User.where( ... ).joins(:shirts).includes(:shirts).limit(50)
不幸的是,这只返回有衬衫的用户。我们需要能够返回有限的用户数组,无论他们是否有相关的衬衫。
有没有办法强制 Rails 使用 LEFT OUTER JOIN 而不是默认的两个查询方法来预先加载关联的对象?
编辑
通过添加一个where
返回 true 的子句,无论关联对象上的值是否为空。至少在 Postgres 上,如果没有关联的对象,它似乎并不介意。
User.where( ... ).includes(:shirt).where("shirts.created_at IS NULL OR shirts.created_at IS NOT NULL")
这解决了问题,但它并不理想,有没有办法使用 LEFT OUTER JOIN 代替默认的两个查询方法?