1

クエリの結果を返すメソッドがあります。メソッドを呼び出すコードは、各結果をループし、sidekiq ワーカーを起動します。私が直面している問題は、ループに実際にかなりの時間がかかっていることです (すべてのワーカーを実行するのにかかる時間とほぼ同じです)。クエリは次のとおりです。

Object.where("last_updated > ?" , 1.days.ago.midnight )

次に、次のことを行います。

objects.each { |o| o.perform_async(something) }

このプロセスをより効率的にする方法を見つけようとしています。その結果、このプロセスが完了するまでに約 10 分かかり、実質的に起動ごとに 20 ミリ秒かかります (クエリが 30,000 件の結果を返す場合)。これを速くする方法はありますか?

4

1 に答える 1

0

last_updatedのインデックスがすでに作成されているようです。次:

Object.select('id, only_columns_you_need').where(...).find_each do |object|
  object.perform_async(something)
end

「オブジェクト」テーブルに多数の列があり、この操作に必要な列が少ない場合、これらの列のみを選択すると、dbとRubyの両方のランドで処理速度が大幅に向上します。

find_eachデフォルトでは、1000のバッチでレコードをロードします。:batch_sizeオプションを使用して微調整します。

アップデート

def do_stuff_to_objects(&stuff)
  Object.select('id, only_columns_you_need').where(...).find_each(&stuff)
end

...

do_stuff_to_objects do |object|
  object.perform_async(something)
end
于 2013-02-13T04:52:11.503 に答える