特定のケースで、ActiveRecord Relation を取得すると.each
、ActiveRecord::Relation で奇妙な動作が発生します。
ActiveRecord::Relationが( source )に委譲:each
するときのようです:to => :to_a
@tasks = Task.find_task(list, {:week_id => 1})
list
基本的に、オブジェクト ( 、および を含むハッシュ:week_id
)を取る長いクラス メソッドがあります。
このfind_task
メソッド内で一連のフィルタリングとクエリが発生しますが、最終的には次の関係を返します@tasks
次に、テンプレートには次のものがあります。
<% @tasks.each do |task| %>
.
.
.
<% end %>
なんらかの理由で、 のサイズに関係なく、@tasks
約 3 分かかります。ActiveRecord::Relation のインスタンスが 2 つのレコードしかない@tasks.to_a
場合でも、それらの呼び出しには 3 分以上かかります。@tasks
to_a
すべての で発生するわけではなく:week_id
、特定の week_id でのみ発生します。次に例を示します。:week_id => 1
SQL は正常に実行され、リレーションが返されます。これは、特定の ActiveRecord::Relation の列挙可能に問題があるようです。
アップデート
アルゴリズム (これはクラス メソッドを意味すると思います) の中で、大量の熱心な読み込みを行います。そのため、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
テンプレートで。
to_a
テンプレートで動作を複製すると、@tasks
関係 を呼び出すのに約 3 ~ 4 分かかることがわかります。
それで、私のサーバーが私にそのすべての時間をテンプレートに費やされていることを教えてくれ、リレーションで列挙可能なものを呼び出すのが永遠にかかるのを見ることができるとき、それはクエリが実行されるときですか? top
プロセスが実行されているのしか見えないのにruby
?