批量运行rails查询

时间:2015-05-25 13:10:31

标签: ruby-on-rails ruby-on-rails-3 performance postgresql cursor

我有一个包含500,000个条目的表A(:name, :address, :phone)。我想运行此查询:

johns = A.where(:name => "John")

此查询应返回150,000个结果。但是运行此查询可以得到以下结果:Killed

我应该如何重写此查询,以便查询在数据库中的1000批次上运行?

4 个答案:

答案 0 :(得分:10)

您需要将find_each batch_size 选项一起使用。

A.where(:name => "John").find_each(batch_size: 1000) do |a|
  # your code
end

答案 1 :(得分:4)

使用find_each的替代方法是使用find_in_batches

有一个明显的区别 - find_each会为您的每个项目提供阻止,并逐项循环您的批次。 find_in_batches会将您的一批项目以数组的形式发送到您的区块。

我假设您的A模型实际上被称为Address。你可以这样做:

Address.where(name: "John").find_in_batches(batch_size: 1000) do |addresses|

  # Your code that you might want to run BEFORE processing each batch ...

  addresses.each do |address|
    # Your code that you want to run for each address
  end

  # Your code that you might want to run AFTER processing each batch ...

end

正如您所看到的,这使您可以更灵活地处理批处理的处理方式。但是,如果您的需求很简单,只需坚持使用find_each

答案 2 :(得分:1)

.in_batches

find_eachfind_in_batches的问题在于您消耗了查询结果。

最干净的解决方案是使用in_batches,因为它会产生实际的查询(不消耗查询):

User.find_in_batches do |users|
  users.select(:id) # error
end

User.in_batches do |users|
  users.select(:id)                   # works as expected
  users.pluck("complext pluck query") # works as expected
end

答案 3 :(得分:0)

 A.where(:name => "John").find_each(batch_size: 1000) do |a|
    # your code
 end