在.html.erb文件中,编写类似这样的内容是很自然的:
<% unless @results.empty? %>
<ul>
<% @results.each do |result| %>
<li>
<%= link_to result.name, '#' %>
</li>
<% end %>
</ul>
<% end %>
其中@results是ActiveRecord .all查询的结果。不幸的是,这会向数据库生成两个查询:第一个查找结果计数(除非条件),第二个查找实际结果。在这种情况下,查询特别昂贵。
我可以简单地将结果转换为数组(可以缓冲整个结果集),或者将复杂逻辑转换为.erb
这两种解决方案似乎都不符合Rails / ActiveRecord的设计理念。
有没有更好的方法来消除重复的查询?
答案 0 :(得分:3)
Rails试图变得聪明,并且在不需要它时不加载整个关联/关系。因此,关系或关联的一些方法看起来像Enumerable
的对应方,但如果未加载关联,则会运行一些sql。 first
,any?
,include?
就是一个例子。
最简单的方法,当您知道这种优化未得到回报的情况时,就是强制加载关系。您可以通过转换为数组to_a
来实现此目的,但您也可以更直接。
@results = Foo.where(...).load
这也将@results保持为关系而不是转换为数组。