左外连接导轨在 where 条件下具有急切加载
Posted
技术标签:
【中文标题】左外连接导轨在 where 条件下具有急切加载【英文标题】:Left outer join rails with eager loading on where condition 【发布时间】:2018-11-17 06:13:45 【问题描述】:我在急切加载具有 where 条件的记录时遇到了系统停机问题。
我在link 上阅读了一篇博客。它谈到了使用带有急切加载关联的 where 条件时的性能问题。
@customers = Customer.all.includes(:invoices, :receipts).where(invoices: status: "open" )
“这会生成两个左外连接。将会发生的情况是数据库将为客户、发票和收据的每个唯一组合返回一行。因此,如果我们有 25 个客户,每个客户有 10 个发票(250总共)和 10 个收据(总共 250 个)。返回的结果集不是 525 条记录,而是更接近 2500 条记录。现在 Rails 必须将所有这些实例化为 ActiveRecord 对象。"
我不明白它为什么会生成 2500 条记录?
【问题讨论】:
【参考方案1】:如果有 25 个客户,每个客户有 10 张发票和 10 张收据,那么使用 'where' 和 'includes' 将生成如下 SQL 查询:
select ...
from customers
left outer join invoices on invoices.customer_id = customers.id
left outer join receipts on receipts.customer_id = customers.id
where invoices.status = 'open'
假设所有发票都打开,此查询将返回 2500 行,因为左外连接查询将创建客户、发票和收据表的所有可能组合,即 25 x 10 x 10。这就是左外连接的方式工作。
ActiveRecord 然后将获取这 2500 行,将它们合并在一起,并创建相当少的活动记录对象。
在生成的活动记录对象中,每条记录只会存在一次。例如,这个@customers 数组中只有 10 个项目:
@customers = Customer.all.includes(:invoices, :receipts).where(invoices: status: "open" )
此外,每张发票和收据将仅作为一条记录存在,而不是像查询返回的行中那样重复多次。
【讨论】:
感谢您的回答。第一个左外连接的输出会是第二个左外连接的输入吗? 我值得升职吗? :-)以上是关于左外连接导轨在 where 条件下具有急切加载的主要内容,如果未能解决你的问题,请参考以下文章