在某些情况下,当我得到一个ActiveRecord的关系,我在一个ActiveRecord遇到奇怪的行为与.each
::关系Rails的活动记录关系枚举
这似乎是在ActiveRecord的::关系代表:each
到:to => :to_a
( source)
@tasks = Task.find_task(list, {:week_id => 1})
基本上,有一个长的类方法,它采用一个对象(list
,并用:week_id
散列)
过滤一束&查询发生这种find_task
方法中,但它最终返回一个关系到@tasks
然后,在模板中,我有:
<% @tasks.each do |task| %>
.
.
.
<% end %>
无论出于何种原因,无论是大小为@tasks
,大约需要3分钟。我可以通过调用@tasks.to_a
来复制相同的行为即使@tasks
,ActiveRecord :: Relation的实例只有两条记录,在它们上调用to_a
需要> 3分钟。
它不会发生在所有:week_id
S,只能在特定的week_id,例如::week_id => 1
的SQL执行罚款,我得到一个关系回来,它只是似乎是一个枚举上一个问题特定的ActiveRecord ::关系。
更新
算法(我认为这意味着类方法),我做的预先加载的里面很多。所以Postgres做了很多LEFT OUTER JOIN
s,我已经索引了所有需要发生的表。
一个解释分析显示,所有扫描都是index scans
,事实证明,查询执行得很好,有很多急切的加载......并且我得到一个渴望加载的'ActiveRecord :: Relation'回到合理的数量时间。
更新2 虽然这个过程是服用3分钟,我看到了几秒钟一个Postgres处理运行,然后我看到这3分钟我的输出top
:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
8685 dylan 20 0 3407m 2.6g 904 R 99.7 69.1 1:14.49 /usr/local/bin/ruby script/rails s
当它终于结束时,服务器显示这个;
- 预先加载:
200 ms
,139 ms
然后 - 大的SQL查询,有很多
LEFT OUTER JOINS in 33,000 ms
,(长,但不是其中大部分是),那么 - 模板
257,000 ms
。
当我复制模板的行为我看到它大约需要3-4分钟拨打to_a
在@tasks
关系。
所以,当我的服务器告诉我所有的时间都花在模板上,而且我可以看到调用一个关于enumerable的关系需要永远的时间,是当查询被执行时?尽管在top
我只能看到ruby
进程正在运行?