2016-09-08 5 views
0

データに誤りがあり、データを修正するためにdata_migrationを書き込もうとしています。 1milの不完全なレコードがあります。データを修正するためのActiveRecord関係を連続グループに分割する方法は?

私はデータベース全体をロックしないようにこれらのレコードをグループに分割する最も良い方法は何ですか? (障害のあるデータ)

apples = Apple.where(seed: "rotten") 

は私がこれを行うにはどうすればよいの5000バッチでこれら​​を更新したいと言う:

は、私はこのクエリを持って言いますか?

今私はこのようなものを持っています...しかしそれは変です。それ以上のレコードがなくなるまで、最初の5000回、次の5000回をどうすればいいですか?複雑さのために、1,104,000件のレコードがあり、現在は1,105,000件の非円形レコードがあります。

class ChangeApples < ActiveRecord::Migration 
    def self.up 
    disable_ddl_transaction! 

    batch_separator = 20 

    apples = Apple.where(core:"rotten") 

    (0...batch_separator).each do |modulo| 
     batch = apples.where("id % #{batch_separator} = #{modulo}") 
     Rails.logger.info("Updating #{batch.count} apples with ids: #{batch.pluck(:id)}.") 

     batch.update_all(eventable_type: "Edible") 
    end 
    end 

    def self.down 
    raise ActiveRecord::IrreversibleMigration 
    end 
end 

答えて

0

一つのオプションは次のようになります:

batch_separator = 5000 
batches   = 0 
while Apple.where(core:"rotten"). 
      limit(batch_separator). 
      update_all(eventable_type: "Edible") > 0 do 
    puts "Updating batch #{batches += 1}" 
end 

未テストコード

は、ここに私の現在のソリューションです。

ループ内にスリープを入れ、コミットすることもできます(自動的に発行されない場合)。それは全体的な効率の面で理想的ではありませんが、忙しいOLTPデータベースに要求をあふれさせたくない場合は、それほど悪い方法ではありません。

関連する問題