Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails rake任务中的海量数据更新_Ruby On Rails_Ruby_Postgresql_Rake Task - Fatal编程技术网

Ruby on rails rake任务中的海量数据更新

Ruby on rails rake任务中的海量数据更新,ruby-on-rails,ruby,postgresql,rake-task,Ruby On Rails,Ruby,Postgresql,Rake Task,我有一个名为PageDensity的模型,它有大约500万行 当我创建项目PageDensity表时,在densitycoulmn中存储了精度为5位小数的浮点 现在要求改为四舍五入到小数点后两位 我只是写了一个任务来绕过所有的密度,但它使系统变得如此沉重,以致于出现问题。即使我不能使用查询,因为我的舍入是位更改,如0.57500将舍入为0.57,0.57600将舍入为0.58 到目前为止,我所尝试的只是: task round_densities: :environment do a

我有一个名为
PageDensity
的模型,它有大约500万行

当我创建项目
PageDensity
表时,在
density
coulmn中存储了精度为5位小数的浮点

现在要求改为四舍五入到小数点后两位

我只是写了一个任务来绕过所有的
密度
,但它使系统变得如此沉重,以致于出现问题。即使我不能使用
查询
,因为我的舍入是位更改,如
0.57500
将舍入为
0.57
0.57600
将舍入为
0.58

到目前为止,我所尝试的只是:

  task round_densities: :environment do
    application_object = ApplicationController.new
    time = Benchmark.realtime do
      ActiveRecord::Base.transaction do
        PageDensity.all.each {|p| p.update_attributes(density: application_object.round_number(p.density))}
      end
    end
    puts '***************************************'
    puts "Total Time Consumed #{time} seconds"
    puts '***************************************'
  end
我还尝试查询舍入,但失败:

select round(0.00500, 2)
#this returns 0.01 as this should return 0.00

我正在使用
postgres
进行
psql查询
或使用
rails

您应该使用批处理,以便进行更改

PageDensity.all.each
与:

检查

但要做到这一点,您必须删除实际上毫无用处的事务


Sideremark,如果没有要触发的回调,请替换:

p.update_attributes(density: application_object.round_number(p.density))
与:


这将节省一些额外的时间。

听起来您的舍入要求与正常舍入相比仅差0.001

在这种情况下,我认为您可以运行sql更新:

update page_densities set density = round(density - 0.001, 2)
这将是这样的:

0.011 => round(0.010, 2) => 0.01
0.015 => round(0.014, 2) => 0.01
0.016 => round(0.015, 2) => 0.02
0.02  => round(0.019, 2) => 0.02

我强烈建议您使用
.all.find\u each
更改
.allbatches@apneadiving接得好,谢谢。这肯定会有所不同,但不是那样much@Matt我试过了,但没能提出这样的问题。因为这不同于我在问题中解释的普通取整查询。不过,我不太明白你的取整逻辑。您只需要截断最后3位吗?@Matt no.
0.00100到0.00500
将向下舍入,即
0.00
。而
0.00600到0.00900
将被四舍五入,即
0.01
。希望这是有道理的为什么你说交易是无用的?在我看来,失败不会带来诚信问题。所有元素都是独立的,这只是减少了内存使用。但不会改变所花费的时间。事实并非如此,因为一次加载内存中的所有内容会减慢所有操作的速度。毫无疑问,sql总是比orm操作好,我的答案只是优化了orm路径似乎是合法的。让我试一试628391张唱片仍然需要29分钟。有进一步改进的想法吗?恐怕没什么好主意。你必须以这样或那样的方式检查所有的记录。如果
密度
不总是有一个值,那么您可以使用
进行过滤,其中密度不为空
——但是考虑到您的列和表名,这种情况似乎不太可能发生。运气不好,
字段中总是有一些值
update page_densities set density = round(density - 0.001, 2)
0.011 => round(0.010, 2) => 0.01
0.015 => round(0.014, 2) => 0.01
0.016 => round(0.015, 2) => 0.02
0.02  => round(0.019, 2) => 0.02