Vat*_*ain 5 activerecord ruby-on-rails
我想对数据库中的数百万条记录执行批处理操作。
根据ActiveRecord文档,有两种方法可以执行批量操作,即#find_in_batches& #in_batches。Enumerator但是,除了一个返回 an而另一个返回 an之外,我似乎找不到它们之间的任何区别ActiveRecord Relation。
因此,考虑到它们具有不同的性能,我想知道哪种在哪种情况下表现更好。并且,除了原始 SQL 之外,是否还有更好的方法来有条件地更新数百万行?
简而言之,find_in_batches生成每批找到的记录in_batches,同时生成ActiveRecord::Relation对象
所以下面的代码:
Post.find_in_batches do |group|
group.each { |post| puts post.title }
end
Run Code Online (Sandbox Code Playgroud)
每批次仅向数据库发送一个查询,以检索该批次的所有帖子数据:
Post.find_in_batches do |group|
group.each { |post| puts post.title }
end
Run Code Online (Sandbox Code Playgroud)
然而:
Post.in_batches do |group|
group.each { |post| puts post.title }
end
Run Code Online (Sandbox Code Playgroud)
将每批发送两个查询到数据库。获取该批次帖子 ID 的第一个查询:
SELECT "posts".* FROM "posts" WHERE ...
Run Code Online (Sandbox Code Playgroud)
第二个查询获取该批次的所有帖子数据:
Post.in_batches do |group|
group.each { |post| puts post.title }
end
Run Code Online (Sandbox Code Playgroud)
更多细节:
如果您在此处查看这两个函数的源代码,您将看到find_in_batches实际上调用in_batches时传入了load: true参数。然而,默认值load是false在in_batches。
如果您进一步查看in_batches使用 value 的 for 部分load,它将如下所示:
SELECT "posts"."id" FROM "posts" WHERE ...
Run Code Online (Sandbox Code Playgroud)
原始解释可以在这里找到:https://www.codehub.com.vn/Difference- Between-find_in_batches-vs-in_batches-in-Ruby-on-Rails
您必须查看源代码才能了解此处的性能差异 -
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
Run Code Online (Sandbox Code Playgroud)
in_batches请注意如何调用该方法以及如何将结果存储在数组中。这会占用更多内存。in_batches因此这里是一种更有效的方法。
| 归档时间: |
|
| 查看次数: |
11786 次 |
| 最近记录: |