find_in_batches
ここで使用されているソースがありますfind_each
:
http://apidock.com/rails/ActiveRecord/Batches/find_in_batches
[ソースリンクを表示] をクリックします。重要な行は次のとおりです。
relation = relation.reorder(batch_order).limit(batch_size)
records = relation.where(table[primary_key].gteq(start)).all
と
records = relation.where(table[primary_key].gt(primary_key_offset)).to_a
バッチで処理し、次のバッチを選択するには、プライマリ インデックスまたはその他の一意のインデックスでレコードを並べ替える必要があります。created_at
一意ではないため、バッチを実行できません。created_at
ただし、 unique による順序付けと選択を混在させることもできますid
。
relation = relation.reorder('created_at ASC, id ASC').limit(batch_size)
records = relation.where(table[primary_key].gteq(start)).all
#....
while records.any?
records_size = records.size
primary_key_offset = records.last.id
created_at_key = records.last.created_at
yield records
break if records_size < batch_size
if primary_key_offset
records = relation.where('created_at>:ca OR (created_at=:ca AND id>:id)',:ca=>created_at_key,:id=>primary_key_offset).to_a
else
raise "Primary key not included in the custom select clause"
end
end
created_at
同じ値を持つレコードが何回も繰り返されないことが確実な場合は、バッチ処理で唯一のキーとしてbach_size
使用できます。created_at
created_at
とにかく、効率的にするにはインデックスが必要です。