Какой самый эффективный способ перебора всей таблицы с использованием Datamapper? - PullRequest
2 голосов
/ 15 мая 2011

Какой самый эффективный способ перебора всей таблицы с использованием Datamapper?

Если я сделаю это, попытается ли Datamapper извлечь весь набор результатов в память перед выполнением итерации?Предположим, ради аргумента, что у меня есть миллионы записей и что это невозможно:

Author.all.each do |a|
  puts a.title
end

Есть ли способ, с помощью которого я могу сказать Datamapper загружать результаты порциями?Достаточно ли умен, чтобы знать, что делать это автоматически?

Ответы [ 3 ]

4 голосов
/ 15 мая 2011

Спасибо, Николас, я действительно придумал подобное решение. Я принял ваш ответ, поскольку он использует систему dm-pagination Datamapper, но мне интересно, будет ли это одинаково хорошо (или хуже):

while authors = Author.slice(offset, CHUNK) do
  authors.each do |a|
    # do something with a
  end
  offset += CHUNK
end
2 голосов
/ 15 мая 2011

Вам нужен плагин dm-chunked_query: (пример из документации)

require 'dm-chunked_query'

MyModel.each_chunk(20) do |chunk|
  chunk.each do |resource|
    # ...
  end
end

Это позволит вам перебирать все записи в модели, по 20 записей за раз.

РЕДАКТИРОВАТЬ: в приведенном выше примере дополнительно #each после #each_chunk, и это было ненужным. Автор гема обновил пример README, и я изменил приведенный выше код, чтобы он соответствовал.

2 голосов
/ 15 мая 2011

Datamapper запустит только один sql-запрос для приведенного выше примера, поэтому ему придется хранить весь набор результатов в памяти.

Я думаю, что вы должны использовать какую-то нумерацию страниц, если ваша коллекция большая.Используя dm-pagination , вы можете сделать что-то вроде:

PAGE_SIZE = 20
pager = Author.page(:per_page => PAGE_SIZE).pager # This will run a count query
(1..pager.total_pages).each do |page_number|
  Author.page(:per_page => PAGE_SIZE, :page => page_number).each do |a|
    puts a.title
  end
end

Вы можете поиграть с разными значениями для PAGE_SIZE, чтобы найти хороший компромисс между количеством запросов sql и использованием памяти..

...