我有一个 RoR 应用程序和一个 cron rake 任务,例如:
Model.all.each do |m|
if m < some_condition
m.do_something
m.save
end
end
Model
有 1 000 000 条记录(以及 200 000 条可接受的条件)。有什么方法可以提高任务内存使用率?它需要千兆字节的内存,并且 Ruby 进程在生产时被服务器杀死。我的数据库是 PostgreSQL。
我有一个 RoR 应用程序和一个 cron rake 任务,例如:
Model.all.each do |m|
if m < some_condition
m.do_something
m.save
end
end
Model
有 1 000 000 条记录(以及 200 000 条可接受的条件)。有什么方法可以提高任务内存使用率?它需要千兆字节的内存,并且 Ruby 进程在生产时被服务器杀死。我的数据库是 PostgreSQL。
您应该使用 和 之类#find_each
的方法#find_in_batches
。这些将一次只加载一小部分记录。看看ActiveRecord::Batches。
我建议使用find_each
,它会批量生成您的对象。
另外,如果可能的话,应用你在 sql 循环中的条件,所以 ActiveRecord 不必实例化你不使用的对象(因此使用内存):
Model.find_each(:conditions => {:my => :condition}).each do |m|
# do something
end
您可以尝试以下方法:
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