Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails Rails:优化查询N+;1具有相同的表1到表2和范围条件_Ruby On Rails_Ruby_Postgresql_Activerecord_Select N Plus 1 - Fatal编程技术网

Ruby on rails Rails:优化查询N+;1具有相同的表1到表2和范围条件

Ruby on rails Rails:优化查询N+;1具有相同的表1到表2和范围条件,ruby-on-rails,ruby,postgresql,activerecord,select-n-plus-1,Ruby On Rails,Ruby,Postgresql,Activerecord,Select N Plus 1,这是我面临的一个挑战,使用Rails 5(我使用报告N+1查询的服务,他们推荐的解决方案是,但在我的情况下这还不够) 我有一个表节点,一个节点可以有多个与其相关的节点(有一个名为父节点id)的列,它使我能够将一对多关联起来 class Node < ApplicationRecord ... belongs_to :parent_node, foreign_key: :parent_node_id, class_name: 'Node', optional: true, inver

这是我面临的一个挑战,使用Rails 5(我使用报告N+1查询的服务,他们推荐的解决方案是,但在我的情况下这还不够)

我有一个表
节点
,一个
节点
可以有多个与其相关的
节点(有一个名为
父节点id
)的列,它使我能够将一对多关联起来

class Node < ApplicationRecord
  ...
  belongs_to :parent_node, foreign_key: :parent_node_id, class_name: 'Node', optional: true, inverse_of: :nodes
  has_many :nodes, foreign_key: :parent_node_id, class_name: 'Node'
  ...
end
这将触发每个
nd3
变量的SQL查询,因为有另一个作用域修改原始
nds
值,我不能将该条件包括在
nds
值中,因为
nd2
需要不符合
另一个\u范围
中标准的
节点


有没有办法优化这个?

选择{n{n.满足另一个范围标准}
替换
另一个范围


由于您已经获取了所有子项,因此无需再次在数据库中筛选它们,除非在
另一个\u作用域中有
limit
子句,您可以添加另一个关联
有很多:无论什么\u节点,>{另一个\u作用域的条件写在这里},外键::parent\u node\u id,class_name:'Node'
现在你可以这样做了
nds=Node。一些作用域。包括(:nodes,:whatever_nodes)
。我认为@DennisKrupelnik建议了一个合适的答案。为了澄清,您应该使用
#include
方法而不是
#include
进行查询batching@helperhelperov是的。我只是指出它是可以改进的。谢谢,你说得对!,尽管不管怎样,如果我再次遍历所有这些代码(在
每个
部分中),除非条件
作为循环中的第一行,否则只
下一步不是更好吗?您必须对其进行基准测试。对于克鲁比,我会选择
select
# In a controller, including nodes so it does not query inside
nds = Node.some_scope.include(:nodes)
nds.each do |nd|
  ...
  # In a model
  # If I loop inside, there's no extra SQL queries, all good
  nd.nodes.each do |nd2|
    ...
  end
  ...
  # In a model
  # Here's the N+1 issue
  nd.nodes.another_scope.each do |nd3|
    ...
  end
  # Returns a value to the controller
  ...
end