Ruby on rails 批次中的活动记录与批次中的查找

Ruby on rails 批次中的活动记录与批次中的查找,ruby-on-rails,activerecord,Ruby On Rails,Activerecord,我想对来自DB的数百万条记录执行批处理操作 根据ActiveRecord文档,有两种方法可以执行批处理操作,即在批中查找和批中查找。但是,我似乎找不到它们之间的任何区别,除了一个返回枚举数,另一个返回ActiveRecord关系 所以,考虑到它们的性能不同,我想知道在哪种情况下哪个性能更好。还有,除了原始SQL之外,还有什么更好的方法可以有条件地更新数百万行吗?您必须查看源代码才能理解这里的性能差异- def find_in_batches(start: nil, finish: nil, ba

我想对来自DB的数百万条记录执行批处理操作

根据ActiveRecord文档,有两种方法可以执行批处理操作,即在批中查找和批中查找。但是,我似乎找不到它们之间的任何区别,除了一个返回枚举数,另一个返回ActiveRecord关系


所以,考虑到它们的性能不同,我想知道在哪种情况下哪个性能更好。还有,除了原始SQL之外,还有什么更好的方法可以有条件地更新数百万行吗?

您必须查看源代码才能理解这里的性能差异-

def find_in_batches(start: nil, finish: nil, batch_size: 1000, error_on_ignore: nil)
  relation = self
  unless block_given?
    return to_enum(:find_in_batches, start: start, finish: finish, batch_size: batch_size, error_on_ignore: error_on_ignore) do
      total = apply_limits(relation, start, finish).size
      (total - 1).div(batch_size) + 1
    end
  end

  in_batches(of: batch_size, start: start, finish: finish, load: true, error_on_ignore: error_on_ignore) do |batch|
    yield batch.to_a
  end
end

请注意如何调用批处理中的方法,以及如何将结果存储在数组中。这将占用更多内存。因此,批量生产是一种更有效的方法

使用.update_all并同时更新所有行总是比从数据库中取出记录并逐个更新它们要好得多。如果可能的话,这绝对是你的第一选择。我首先要问的是,如果一个方法总是比另一个好,为什么他们会公开这两种方法?仅仅因为一个调用另一个并不意味着它的性能较差,这取决于用例。正如@max所说,更新所有内容都是首选。如果您遇到一些问题超时等,那么跨多个工作人员跨批可能是需要考虑的问题。in_batches是一个较低级别的函数,可用于构建诸如find_in_batches之类的内容。我怀疑,一旦您真正开始遍历记录,使用in_batches实际上会明显加快速度。不管怎么说,这就像比较两种马和一艘宇宙飞船。不要害怕一点原始sql。这并不是自动产生的,因为要更新的值是基于行的动态值——这听起来像是SQL可以实现的。您可以使用子查询、函数、横向联接等。这在一定程度上取决于数据库,但在postgres上,您可以使用外部数据包装器FDW来联接驻留在另一个数据库上的表,就像它位于同一个数据库中一样。没有任何上下文,我同意。但是,仅仅因为一个调用另一个并不意味着它的性能较低……这取决于当前未知的用例。