批量运行rails查询

Hel*_*boy 9 postgresql performance ruby-on-rails cursor ruby-on-rails-3

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

johns = A.where(:name => "John")
Run Code Online (Sandbox Code Playgroud)

此查询应返回150,000个结果.但运行此查询会给我这个结果:Killed.

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

Aru*_*hit 12

您需要使用find_each选项batch_size.

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


Jon*_*Jon 9

使用的替代方法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
Run Code Online (Sandbox Code Playgroud)

如您所见,这为您处理批次的处理方式提供了更多的灵活性。但是,如果您的需求很简单,请坚持使用find_each.


Nat*_*ouy 5

.in_batches

有问题find_each或者find_in_batches是你已经消耗的查询结果。

最干净的解决方案是 using 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
Run Code Online (Sandbox Code Playgroud)