2

Datamapperを使用してテーブル全体を反復処理する最も効率的な方法は何ですか?

これを行うと、Datamapperは反復を実行する前に結果セット全体をメモリにプルしようとしますか?議論のために、私には何百万ものレコードがあり、これは実行不可能であると仮定します。

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

結果をチャンクでロードするようにDatamapperに指示する方法はありますか?これを自動的に行うことを知っているのは十分賢いですか?

4

3 に答える 3

4

おかげで、ニコラス、私は実際に同様の解決策を思いついた。Datamapperのシステムを利用しているので、私はあなたの答えを受け入れましたがdm-pagination、これが同じように(またはもっと悪いことに)うまくいくかどうか疑問に思っています:

while authors = Author.slice(offset, CHUNK) do
  authors.each do |a|
    # do something with a
  end
  offset += CHUNK
end
于 2011-05-15T01:58:51.850 に答える
2

Datamapperは、上記の例では1つの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クエリの数とメモリ使用量の間の適切なトレードオフを見つけることができます。

于 2011-05-15T00:20:14.513 に答える
2

必要なのはdm-chunked_queryプラグインです:(ドキュメントの例)

require 'dm-chunked_query'

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

これにより、モデル内のすべてのレコードを一度に20レコードのチャンクで反復処理できます。

#each編集:上記の例には、の後に余分な#each_chunkものがあり、それは不要でした。gemの作成者がREADMEの例を更新し、それに合わせて上記のコードを変更しました。

于 2011-05-15T02:50:13.243 に答える