在Rails 3.2中,如何" pluck_in_batches"对于一张非常大的桌子

时间:2015-02-08 06:39:42

标签: ruby-on-rails activerecord pluck

我有一个庞大的表Foo,我需要从中获取某个字段中的所有值,Foo.who。

数组有数百万行,但who列中只有几千个不同的值。

如果表格较小,我只需使用Foo.pluck(:who)

如果我使用Foo.find_in_batches do |a_batch|每个集合都是一个Foo记录数组,而不是Foo记录的activerecord集合,那么我不能使用.pluck()和AFAIK提取{{1}的唯一方法}列是通过像who这样迭代数组的东西。

有没有办法从Foo中批量提取.map(&:who)列,而不需要遍历每个批次的每个元素以提取who列?

3 个答案:

答案 0 :(得分:2)

试试这个:

Foo.select(:id, :who).find_in_batches do |a_batch|
  ...
end

答案 1 :(得分:2)

在Rails 5中,您可以使用:

Foo.in_batches do |relation|
  values = relation.pluck(:id, :name, description)
  ...
end

更新:为防止内存泄漏使用:

Foo.uncached do
  Foo.in_batches do |relation|
    values = relation.pluck(:id, :name, description)
    ...
  end
end

答案 2 :(得分:0)

in_batches 已经在引擎盖下运行 pluck(:id)(如果 load 参数是 false,这是默认值)并产生与 where(id: ids_from_pluck) 的关系。那么是否可以直接从关系中获取 id 列表,而无需在 DB 中运行另一个查询:

Foo.in_batches do |relation|
  ids = relation.where_values_hash['id']
end

这应该适用于 Rails 5.x 和 6.x,但依赖于 in_batches 的实现细节,因此将来可能会发生变化。