我有一个RoR应用程序和一个cron rake-task,类似于:
Model.all.each do |m|
if m < some_condition
m.do_something
m.save
end
end
Model
有1 000 000条记录(20万条条件可接受)。有没有办法改善任务内存的使用?它需要几千兆字节的内存,并且Ruby进程在生产时被服务器杀死。我的DB是PostgreSQL。
答案 0 :(得分:2)
您应该使用#find_each
和#find_in_batches
等方法。这些将一次只加载一小部分记录。看看ActiveRecord::Batches。
答案 1 :(得分:2)
我建议使用find_each
,它会分批生成您的对象。
另外,如果可能的话,在sql中应用你在循环中的条件,因此ActiveRecord不必实例化你不使用的对象(因此使用内存):
Model.find_each(:conditions => {:my => :condition}).each do |m|
# do something
end
答案 2 :(得分:1)
您可以尝试以下方法:
def with_gc(enum)
count = enum.count
limit = 100
(0..count).select{|i| i % limit == 0}.each do |index|
new_count = enum.count
raise "query depends on updated param. Expected count #{count}, got #{new_count}" if count != new_count
enum.skip(index).limit(limit).each do |record|
yield record
end
GC.start
end
end
你可以像这样使用它:
with_gc(Model.all) do |m|
if m < some_condition
m.do_something
m.save
end
end