find_each_with_order

上一篇blog,分析了一下find_each的源码,后来又查了一下解决的办法,这里记录一下找到的几种可以代替find_each的方法。

第一种 先排好序,获取到已经排好序的ids数组,然后对数组分组执行

1
2
3
4
5
6
7
batch_size = 512
ids = Thing.order('created_at DESC').pluck(:id) # Replace .order(:created_at) with your own scope
ids.each_slice(batch_size) do |chunk|
Thing.find(chunk, :order => "field(id, #{chunk.join(',')})").each do |thing|
# Do things with thing
end
end

第二种 通过指定好数组区间,然后分组获取,原理和方法一相同,代码如下

1
2
3
4
5
total_records = 50000
batch = 1000
(0..(total_records - batch)).step(batch) do |i|
puts Thing.active.order("created_at DESC").offset(i).limit(batch).to_sql
end