【问题标题】:What's the most efficient way to iterate through an entire table using Datamapper?使用 Datamapper 遍历整个表的最有效方法是什么?
【发布时间】:2011-05-14 22:19:51
【问题描述】:

使用 Datamapper 遍历整个表的最有效方法是什么?

如果我这样做,Datamapper 是否会在执行迭代之前尝试将整个结果集拉入内存?假设,为了争论,我有数百万条记录,这是不可行的:

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

有没有办法告诉 Datamapper 以块的形式加载结果?知道自动执行此操作是否足够聪明?

【问题讨论】:

    标签: ruby datamapper ruby-datamapper


    【解决方案1】:

    谢谢 Nicolas,我实际上想出了一个类似的解决方案。我已经接受了你的回答,因为它使用了 Datamapper 的 dm-pagination 系统,但我想知道这是否会同样好(或更糟):

    while authors = Author.slice(offset, CHUNK) do
      authors.each do |a|
        # do something with a
      end
      offset += CHUNK
    end
    

    【讨论】:

      【解决方案2】:

      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 查询数量和内存使用量之间找到一个很好的平衡点。

      【讨论】:

      • 谢谢,尼古拉斯。我还发布了我自己问题的答案。我很高兴听到关于我的版本的反馈。我认为它们是等价的。
      • 您的解决方案应该同样有效,并且可能更干净。将其抽象为分页感知迭代器会很好,例如Author.each_in_chunks do
      【解决方案3】:

      您想要的是 dm-chunked_query 插件:(来自文档的示例)

      require 'dm-chunked_query'
      
      MyModel.each_chunk(20) do |chunk|
        chunk.each do |resource|
          # ...
        end
      end
      

      这将允许您迭代模型中的所有记录,一次包含 20 条记录。

      编辑:上面的示例在#each_chunk 之后有一个额外的#each,这是不必要的。 gem作者更新了README示例,我把上面的代码改成匹配了。

      【讨论】:

      • 谢谢,这看起来很干净。不过他们有each_chunk(20).each 看起来确实很有趣。为什么不只是each_chunk(20)?让each_chunk 方法占用块。哦,好吧,仍然比我想出的语法更好。
      • 杰森,你是对的。我刚刚查看了代码,#each_chunk 确实产生了一个块,所以我认为我举的例子可能并不完全准确。我将与 gem 作者核实并发布更新以确保。
      • Jason,我联系了 gem 作者,他说我使用的示例可以简化为不需要额外的 #each。我更新了上面的消息以匹配 gem README 中的示例。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-27
      • 2011-04-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多