Ruby on rails 轨道上的奇怪行为;活动记录/视图代码的重写位出乎意料地需要更长的时间来运行,而不是更少的时间

Ruby on rails 轨道上的奇怪行为;活动记录/视图代码的重写位出乎意料地需要更长的时间来运行,而不是更少的时间,ruby-on-rails,ruby-on-rails-3,caching,activerecord,view,Ruby On Rails,Ruby On Rails 3,Caching,Activerecord,View,这有点奇怪 在rails中,我有一个页面,有时需要花费一些时间来加载(大约12秒)。因此,我尝试重新编写它,因为很大一部分使用缓存查询,而不是在它们的关联上使用find,我将在下面解释: 在我尝试加速之前的示例代码: 假设每个用户都属于一个帐户,在它看起来像这样之前 class User < ActiveRecord::Base belongs_to :account end class Account < ActiveRecord::Base end 因此,当查找每个用户的帐户

这有点奇怪

在rails中,我有一个页面,有时需要花费一些时间来加载(大约12秒)。因此,我尝试重新编写它,因为很大一部分使用缓存查询,而不是在它们的关联上使用find,我将在下面解释:

在我尝试加速之前的示例代码:

假设每个用户都属于一个帐户,在它看起来像这样之前

class User < ActiveRecord::Base
belongs_to :account
end

class Account < ActiveRecord::Base
end
因此,当查找每个用户的帐户时,一个单独的查询通过从用户的帐户id中查找来查找该帐户

我试图通过在一个查询中查找所有帐户来加速此页面,首先是via和in(),然后在需要时检测它们,如下所示:

在rails应用程序中,现在有以下代码:

@users = User.all
@all_accounts = Account.where(:id => users.map{ | user | user.account_id } )

<% @users.each do | user | %>
    <%= @all_accounts.detect{ | a | a.id == user.account_id }.name %>
<% end %>
@users=User.all
@all|u accounts=Account.where(:id=>users.map{| user | user.Account_id})
这意味着调用缓存查询的每一行都需要0秒的时间来运行,而不是100秒的单个选择

这就是一切变得非常奇怪的地方…

在第一个示例中,页面呈现的活动记录部分大约需要6000毫秒,视图部分大约需要6000毫秒。总共大约12秒,这是垃圾

我原以为重新编写的代码中包含detect会更快,但是页面上的活动记录部分渲染速度太快,1000毫秒(每秒),而视图部分大约需要30秒

这到底是怎么回事?为什么渲染视图要花费大约半分钟的时间

假设is页面不能按照客户机请求分页。而且它也不能有一个无限的卷轴,整个页面需要呈现得更快。显然,我也可以使用内置在rails中的memcaching,但我们假设这也不是一个选项。而且它在第一次渲染时仍然需要快速加载,然后才能进行memcached


那为什么要花这么长时间才能看到呢?任何在风景区的人都将不胜感激!谢谢

您可以使用rails默认机制在查询中包含关联。 此外,在遍历大型数据集时,应该使用find_each。它批量获取对象,从而保护内存:

@users = User.includes(:account)

<% @users.find_each do | user | %>
  <%= user.account.name %>
<% end %>
@users=User.includes(:帐户)

您可以使用rails默认机制在查询中包含关联。 此外,在遍历大型数据集时,应该使用find_each。它批量获取对象,从而保护内存:

@users = User.includes(:account)

<% @users.find_each do | user | %>
  <%= user.account.name %>
<% end %>
@users=User.includes(:帐户)

这需要一段时间,因为
@all_accounts=Account.where(:id=>users.map{| user | user.Account_id})
实际上并没有运行该查询。查询在实际需要时运行,即调用
detect

它正在为每个用户运行
Account
查询,显然这是一个比原始查询更为强大的查询,因为它每次都要拉大量的
Account
s,因此等待时间很长


解决方案显然是按照其他人的建议,使用
includes
,但要坚持
。所有
都放在
帐户的末尾,让该查询在第一个实例中执行也可能会起作用。

这需要一段时间,因为
@all\u accounts=Account.where(:id=>users.map{| user | user.account_id})
实际上并不运行该查询。该查询在实际需要时运行,即在调用
detect
时运行

它正在为每个用户运行
Account
查询,显然这是一个比原始查询更为强大的查询,因为它每次都要拉大量的
Account
s,因此等待时间很长


解决方案显然是按照其他人的建议,使用
includes
,但要粘贴
。在
帐户的末尾执行所有的
查询,也可以在第一个实例中执行该查询。

为什么不在你的用户查询中设置一个:include?它就像你在@all\u帐户上的小补丁一样工作……为什么不呢在你的用户查询中设置一个:include?它就像你在@all_账户上的小补丁一样工作。。。
@users = User.includes(:account)

<% @users.find_each do | user | %>
  <%= user.account.name %>
<% end %>