1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Rails 4 - Active Record Query Interface

Posted at

批量查询记录

我们时常会碰到需要一次性处理大量记录的要求,比如说为所有的用户发送电子邮件:

User.all.each do |user|
  NewsLetter.weekly_deliver(user)
end

这样的做法虽然能完成工作,但是却很没效率,特别是当数据库里的记录数量非常大的时候,User.all 会把所有的记录一次性获取,然后逐条实例化,并把最终的结果数组保存在内存当中,这种消耗是非常巨大的。

Rails 提供了两个用于批量查询记录的方法,find_eachfind_in_batches

find_each

find_each 方法查询一批记录并逐条提取至 block 中执行,一批次的数量默认是 1000 条,这个缺省值是和 find_in_batches 相同的。

User.find_each do |user|
  NewsLetter.weekly_deliver(user)
end

当然,我们可以手动指定一批次的数量:

User.find_each(batch_size: 5000) do |user|
  NewsLetter.weekly_deliver(user)
end

另外,默认的查询是以主键按升序来完成的,这就要求主键必须得是数字;我们还可以指定查询的起始位置:

User.find_each(start: 2000, batch_size: 2000) do |user|
  NwesLetter.weekly_deliver(user)
end

假设你想要同时使用多个代工(workers)来帮助你处理批量工作,就可以用这两个选项来为每一个代工指定目标区间了。

find_in_batches

find_each 相比,find_in_batches 方法在获得一批记录之后,并不是逐条提取而是把这一批记录作为一个数组全部提取至 block 中执行。

Invoice.find_in_batches(include: :invoice_lines) do |invoices|
  export.add_invoices(invoices)
end

include 选项允许你指明需要和模型一起加载的关联关系*,其他的选项和 find_each 方法相同。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?