ActiveRecord - 加速此铁路迁移

时间:2016-02-02 09:58:36

标签: ruby-on-rails

我有什么办法可以加快迁移速度。随着一些新列的添加,需要填充历史数据。

它需要填充超过200,000行,大约需要一个小时。我没有使用本机sql作为我们的测试,本地开发和部署的sql数据库都是不同的,需要3个不同的sql脚本,所以我认为活动记录最好这样做。

迁移执行简单计算,将两个值相乘以创建存储的新值。

class PopulateMissingItems < ActiveRecord::Migration
  def change
    begin
      Item.where('items.item_status_id' => [Item::HISTORICAL]).find_each(start: 0, batch_size: 2000) do |item|
        item.ignore_update_user = true # don't update the user id

        item.ine_items.each do |line_item|
          line_item.apply_exchange_rate (item.us_exchange_rate)
        end
      end
    rescue Exception => e
      puts e.message
    end
  end
end

1 个答案:

答案 0 :(得分:0)

您可以利用ActiveRecord的update_all方法,该方法可以在单个SQL语句中更新给定关系的所有记录。

假设新的total整数列已添加到现有LineItem模型,其中包含两个现有some_intother_int列,则迁移可按如下方式编写:

class PopulateMissingItems < ActiveRecord::Migration
  def change
    begin
      Item.where(item_status_id: [Item::HISTORICAL]).find_each(start: 0, batch_size: 2000) do |item|
        item.line_items.update_all('total = some_int + other_int')
      end
    rescue Exception => e
      puts e.message
    end
end

这将为每个Item执行一个update语句。也可以使用单个语句更新所有项目的所有订单项,但这取决于其他因素。

一个重要的注意事项是update_all(来自docs):

  

它不会实例化所涉及的模型,也不会触发Active Record回调或验证。