Rails 4更快地列出模型中的所有记录

时间:2014-07-02 03:15:17

标签: jquery ruby-on-rails performance mysqli

我会保持这个简短。我有一个包含6,000条记录的产品型号(不多)。当我在视图中运行循环以简单列出表中的所有记录时,类似于此..

<% Product.all.each do |product|  %>
   <%= product.serial_number %> <br />
<% end %>

..在我的视图中加载并在网页中显示我的记录需要13.02秒。这是我的开发环境和prod ENV,我尝试使用mySQL和sqlite数据库。似乎没什么区别。

但是,当我在rails控制台中运行此查询时,它在88.2ms(不到1秒)内完成。

什么可以举起来?

2 个答案:

答案 0 :(得分:2)

你是在一个领域之后?使用pluck。这正是它的用途。

<% Products.pluck(:serial_number).each do |serial_number| %>
   <%= serial_number %> <br />
<% end %>

这两者都会生成更高效的SQL(select serial_number而非select *),并绕过为每个返回的结果实例化ActiveRecord对象的步骤,只有这样才能访问该模型的单个属性。

  

但是,当我在rails控制台中运行此查询时,它在88.2ms(不到1秒)内完成。

除非你真的开始迭代结果,否则Rails不会任何事情。当您尝试访问结果时,Rails实际上只实例化记录。


回复:您的评论

  

然而,我实际上只是以上面的例子为例。我实际上显示了每条记录的所有字段。对此有什么窍门?

然后,您不应该使用循环,如样本所示。使用部分和collection rendering很多比自己迭代结果更快

创建一个名为app/views/products/_product.html.erb的视图,并将&#34; body&#34;该文件中的循环。它可能看起来像这样:

<div class="product">
  Name: <%= link_to product, product.name %><br/>
  Serial Number: <%= product.serial_number %>
</div>

然后,在顶级视图中,使用该parial渲染整个集合:

render partial: 'product', collection: Product.all

答案 1 :(得分:1)

<强>加入

最重要的是,您必须加入可以加入的关联。查看服务器日志,如果有很长的数据库提取列表,请查看显示页面的时间。例如,如果您的ProductUser相关联,您将看到产品列表中的一个“SELECT”,然后为您的用户看到一百个“SELECT”。您可能想要使用此语法

<% Products.joins(:user).each do |product|  %>
  <%= product.serial_number %> <br />
<% end %>

请注意,您必须适应您的代码(我使用user作为示例),这完全取决于您的关联。请参阅指南here

中的更多内容

请注意joins执行“INNER JOIN”,并删除所有具有nil引用的记录。如果是您的情况,您可以使用includes

使用“预先加载”技术
Products.includes(:user).each do |product|

<强> Find_each

或者,尝试使用find_each,它将批量处理您的记录以节省服务器电源。在guides

中查看有关它的更多详细信息
Products.find_each do |product| 

<强>缓存

或者,您可以使用caching来提高效果

Products.find_each do |product|
  cache product do
    ...
  end
end

<强>分页

并且如果可能的话,还考虑使用分页来限制从数据库中获取的记录数