在进行大数据迁移(几十万行)时,我遇到了巨大的时间和计算能力挑战.我正在开发一种处理rails中大量数据的服务.随着我们对设计的了解越来越多,我们的模型也在不断变化.这导致我们的数据库(Postgres 9.0数据库)进行了大量迁移.这些迁移通常还包括对数据本身的某种迁移.昨天我们发现我们需要将模型上的“text”属性移动到一个单独的模型中,这样该属性不再仅仅是模型上的属性,而是一对多关系.
我的迁移看起来像这样:
def self.up create_table :car_descriptions do |t| t.integer :car_id t.text :description t.timestamps end Car.find_each do |car| if car.description.present? car.descriptions.build :description => car.description end car.save end remove_column :cars,:description end
现在的问题是,这运行得非常慢,更糟糕的是,如果我设置一个计数器并打印出进度,我可以看到迁移的运行速度越来越慢.在我的活动监视器中,我可以看到ruby进程占用了越来越多的内存.
所以我的问题是 – 是否有更好的方法来进行大数据迁移?
解决方法
您不应在此处使用ActiveRecord将数据从Car模型迁移到CarDescription模型.相反,你应该反驳运行原始sql(从迁移运行).在我上一份工作中,我们遇到了大量数据的问题,并且运行原始sqls导致更快的迁移(尽管有时候快速仍然是5-6小时).在经历了许多痛苦经历之后,我们开发的另一种做法是,我们总是将数据库从生产复制到我们的登台服务器,并在登台时至少运行两次迁移.我们总是提出一些流程(特定于迁移),这可以节省大量时间.有时包括进程,手动删除某些索引,运行迁移并再次手动创建这些索引.
在目前的情况下,sql看起来像这样:
INSERT INTO car_descriptions(car_id,description) SELECT id,description FROM cars