繁体   English   中英

Rails“包含”方法并避免N + 1查询

[英]Rails “includes” Method and Avoiding N+1 Query

我不完全了解Rails的includes方法,我遇到了一个我想澄清的问题。 我有一个具有has_many :membershas_many :lists董事会模型(还有一个has_many :cards列表)。 在以下板控制器中show方法如下所示:

def show
  @board = Board.includes(:members, lists: :cards).find(params[:id])
  ...
end

为什么这里需要includes方法? 为什么我们不能只使用@board = Board.find(params[:id])然后通过@board.members@board.lists访问成员和列表? 我想我不是真的不明白为什么我们需要预取。 如果有人可以详细说明为什么这对SQL查询更有效,那将是非常棒的。 谢谢!

根据Rails文档:

急切加载是一种使用尽可能少的查询来加载Model.find返回的对象的关联记录的机制。

当您简单地加载一条记录并稍后查询其不同的关系时,您每次都必须运行一个查询。 还是从Rails文档中获取以下示例:

clients = Client.limit(10)

clients.each do |client|
  puts client.address.postcode
end

该代码执行一次数据库调用11次以完成一些琐碎的事情,因为它必须每次都进行一次查找。

将上面的代码与此示例进行比较:

clients = Client.includes(:address).limit(10)

clients.each do |client|
  puts client.address.postcode
end 

该代码执行两次数据库调用,因为所有必要的关联都包含在开始时。

这是指向Rails文档相关部分的链接。

额外

最近要注意的一点:如果使用类似的关联模型执行更复杂的查询,则:

Board.includes(:members, lists: :cards).where('members.color = ?', 'foo').references(:members)

您需要确保包含附加的references(:used_eager_loaded_class)以完成查询。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM