使用方法update_all [英] update_all with a method

查看:300
本文介绍了使用方法update_all的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们说我有一个模型:

Lets say I have a model:

class Result < ActiveRecord::Base
  attr_accessible :x, :y, :sum
end

而不是这样做

Result.all.find_each do |s|
  s.sum = compute_sum(s.x, s.y)
  s.save
end

假定 compute_sum 是可用的方法,并且执行某些无法转换为SQL的计算。

assuming compute_sum is a available method and does some computation that cannot be translated into SQL.

def compute_sum(x,y)
  sum_table[x][y]
end

是否可以使用 update_all ,可能类似于:

Is there a way to use update_all, probably something like:

Result.all.update_all(sum: compute_sum(:x, :y))

我要更新的记录超过80,000条。 find_each 中的每个记录都会创建自己的 BEGIN COMMIT 查询,并且每个记录都会单独更新。

I have more than 80,000 records to update. Each record in find_each creates its own BEGIN and COMMIT queries, and each record is updated individually.

或者还有其他更快的方法吗?

Or is there any other faster way to do this?

推荐答案

如果不能将compute_sum函数转换为sql,则无法一次对所有记录执行update_all。您将需要遍历各个实例。但是,如果列中有很多重复的值集,则可以加快速度,方法是每组输入仅进行一次计算,然后每次计算进行一次质量更新。例如

If the compute_sum function can't be translated into sql, then you cannot do update_all on all records at once. You will need to iterate over the individual instances. However, you could speed it up if there are a lot of repeated sets of values in the columns, by only doing the calculation once per set of inputs, and then doing one mass-update per calculation. eg

Result.all.group_by{|result| [result.x, result.y]}.each do |inputs, results|
  sum = compute_sum(*inputs)
  Result.update_all('sum = #{sum}', "id in (#{results.map(&:id).join(',')})")
end

您可以将result.x,result.y替换为

You can replace result.x, result.y with the actual inputs to the compute_sum function.

编辑-忘记在group_by块中的result.x,result.y周围放置方括号。

EDIT - forgot to put the square brackets around result.x, result.y in the group_by block.

这篇关于使用方法update_all的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆