Rails 4查询性能&将查询移出视图

时间:2016-01-22 15:51:26

标签: ruby-on-rails ruby-on-rails-4 query-performance

我对rails的某些方面相当新,并且在我的视图中有一个查询,这确实减慢了我的响应时间。我确信一些铁路专家可以在这个问题上给我打电话。

模型 Company.rb

class Company < ActiveRecord::Base
  has_many :contacts, inverse_of: :company
  has_many :projects, inverse_of: :company
end

控制器 companies_controller.rb

def index
  @companies = Company.all.includes(:contacts, :projects)
end

查看 index.html.rb
(编辑)我在这里做的是从所有属于特定公司的项目中获得:material_total_weight_lbs的总和。

<% @companies.each do |company| %>
  <td>
    <%=  
      number_with_delimiter(
        @companies.where(id: company.id).sum(:material_total_weight_lbs)
      ) 
    %>
  </td>
<% end %>

:material_total_weight_lbs是项目属性。

我的rails服务器输出看起来像这样......

...  
   (0.6ms)  SELECT COUNT(*) FROM "projects" WHERE "projects"."company_id" = $1  [["company_id", 511]]
   (0.7ms)  SELECT SUM(material_total_weight_lbs) FROM "companies" LEFT OUTER JOIN "contacts" ON "contacts"."company_id" = "companies"."id" LEFT OUTER JOIN "projects" ON "projects"."company_id" = "companies"."id" WHERE "companies"."id" = $1  [["id", 511]]
   (0.7ms)  SELECT COUNT(*) FROM "projects" WHERE "projects"."company_id" = $1  [["company_id", 512]]
   (0.8ms)  SELECT SUM(material_total_weight_lbs) FROM "companies" LEFT OUTER JOIN "contacts" ON "contacts"."company_id" = "companies"."id" LEFT OUTER JOIN "projects" ON "projects"."company_id" = "companies"."id" WHERE "companies"."id" = $1  [["id", 512]]
   (1.0ms)  SELECT COUNT(*) FROM "projects" WHERE "projects"."company_id" = $1  [["company_id", 513]]
   (1.2ms)  SELECT SUM(material_total_weight_lbs) FROM "companies" LEFT OUTER JOIN "contacts" ON "contacts"."company_id" = "companies"."id" LEFT OUTER JOIN "projects" ON "projects"."company_id" = "companies"."id" WHERE "companies"."id" = $1  [["id", 513]]
  Rendered companies/index.html.erb within layouts/application (3454.9ms)
   (1.1ms)  SELECT COUNT(*) FROM "companies"
   (1.3ms)  SELECT COUNT(*) FROM "projects" WHERE (scheduled_start_date > '2015-01-22 15:25:07.717772')
   (1.0ms)  SELECT COUNT(*) FROM "materials"
  Rendered layouts/_navigation.html.erb (8.0ms)
  Rendered layouts/_topnavbar.html.erb (0.1ms)
  Rendered layouts/_footer.html.erb (0.2ms)
Completed 200 OK in 3509ms (Views: 2664.9ms | ActiveRecord: 843.6ms)

问题
1.将这种逻辑移出视野的最佳做法是什么?
2.如何设置此查询以获得最佳性能?

谢谢你们。

2 个答案:

答案 0 :(得分:0)

我真的没有得到你想要做的事情。

<% @companies.each do |company| %>
  <td>
    <%=  
      number_with_delimiter(
        @companies.where(id: company.id).sum(:material_total_weight_lbs)
      ) 
    %>
  </td>
<% end %>

我认为这应该只是

<% @companies.each do |company| %>
  <td>
    <%=  
      number_with_delimiter(
        company.material_total_weight_lbs
      ) 
    %>
  </td>
<% end %>

答案 1 :(得分:0)

由于material_total_weight_lbs属性位于项目中,并且公司有has_many项目,因此您应该尝试从那里获取它。

<% @companies.each do |company| %>   <td>
    <%=  
      number_with_delimiter(
        company.projects.sum(:material_total_weight_lbs)
      ) 
    %>   </td> <% end %>

性能很慢,因为在每个循环中你再次使用@companies,导致执行多个查询。理想的方法是创建范围,或者您也可以使用装饰器清除您的视图。