这是我面临的一个挑战,使用 Rails 5(我使用报告 N+1 查询的Skylight服务,他们推荐的解决方案在这里,但在我的情况下还不够)。
我有一个表nodes
,一个Node
可以有几个nodes
与之相关的(有一个名为 的列parent_node_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
重要
层次结构的级别最大为 1。这意味着node.nodes.first.node
不会发生 a。node
有 a 的Aparent_node
没有了nodes
。
问题是我正面临 N+1 的性能问题,nodes
因为在原始查询中包含 是不够的,因为在循环中我用不同的范围查询每条记录。这是一个暴露问题的示例代码:
# 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
无论如何,这将触发每个变量的 SQL 查询,nd3
因为another_scope
它会修改原始nds
值,并且我不能在nds
值中包含条件,因为nodes
不符合条件another_scope
的nd2
.
有没有办法优化这个?