左外连接导轨在 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 条件下具有急切加载的主要内容,如果未能解决你的问题,请参考以下文章

左外连接 where条件 on条件

具有许多表、左外连接和 where 子句的 LINQ 查询

LINQ:具有多个条件的左外连接

Laravel 查询构建器与 where 左外连接

什么是左外连接 SQLserver

使用内连接,左外连接,交叉应用获取语法错误与 Where 子句