更新 rake 任务中的大量数据

Update huge data in rake task

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

当我创建项目时 PageDensity table 在 density 库里存储了 5 位小数精度的浮点数。

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

我只是写了一个任务来绕过所有 densities 但它使系统变得如此沉重以至于卡住了。即使我不能使用 query,因为我的四舍五入有点变化,例如 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 query 或使用 rails ?

你应该使用批处理,所以改变

PageDensity.all.each

与:

PageDensity.all.find_each

检查doc

但要这样做,您必须删除实际上无用的交易。


旁注,如果没有回调触发,替换为:

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

与:

p.update_column(: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