批量查询记录
我们时常会碰到需要一次性处理大量记录的要求,比如说为所有的用户发送电子邮件:
User.all.each do |user|
NewsLetter.weekly_deliver(user)
end
这样的做法虽然能完成工作,但是却很没效率,特别是当数据库里的记录数量非常大的时候,User.all
会把所有的记录一次性获取,然后逐条实例化,并把最终的结果数组保存在内存当中,这种消耗是非常巨大的。
Rails 提供了两个用于批量查询记录的方法,find_each
和 find_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
方法相同。