Rails: работа с большим набором - PullRequest
1 голос
/ 29 апреля 2011

У меня есть несколько сценариев rake, которые работают с коллекциями сотен тысяч элементов.

Часто на моем сервере заканчивается память и происходит сбой сценария.Я предполагаю, что это потому, что мой код выглядит следующим образом:

Asset.where(:archived => false).each { |asset| asset.action! }

Насколько я могу судить, Rails извлекает весь набор в память, а затем перебирает каждый экземпляр.

Похоже, мой сервер не может загрузить сразу 300 000 экземпляров Asset, поэтому для уменьшения требований к памяти мне пришлось прибегнуть к чему-то вроде этого:

collection = Asset.where(:archived => false) # ActiveRecord::Relation
while collection.count > 0
  collection.limit(1000).each { |asset| asset.action! }
end

К сожалению, это не кажется очень чистым.Это становится еще хуже, когда действие не удаляет предметы из набора, и я должен следить с offset s тоже.У кого-нибудь есть предложения относительно лучшего способа разделения данных или более длительного хранения отношения и загрузки только строк по мере необходимости?

1 Ответ

2 голосов
/ 29 апреля 2011

Метод find_each разработан для помощи в таких ситуациях. Это будет

Asset.where(:archived => false).find_each(:batch_size=>500) do |asset|
  asset.stuff
end

по умолчанию, размер партии 1000

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...