0

我有一个 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。

4

3 回答 3

2

您应该使用 和 之类#find_each的方法#find_in_batches。这些将一次只加载一小部分记录。看看ActiveRecord::Batches

于 2013-02-14T15:17:51.430 回答
2

我建议使用find_each,它会批量生成您的对象。

另外,如果可能的话,应用你在 sql 循环中的条件,所以 ActiveRecord 不必实例化你不使用的对象(因此使用内存):

Model.find_each(:conditions => {:my => :condition}).each do |m|
  # do something
end
于 2013-02-14T15:20:17.090 回答
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
于 2013-02-14T16:14:07.120 回答