迁移速度非常慢

时间:2018-12-07 15:32:38

标签: ruby-on-rails ruby ruby-on-rails-5

我的最新迁移运行得很慢(600秒),即使执行不多

我有一个模型,其中包含以逗号分隔的字符串格式的标签,如下所示:

Model.tags =“ TAG1,TAG2,TAG3”

我想创建一个新的Tag模型,该模型与我的模型具有has_and_belongs_to_many关系

这是迁移

def self.up
rename_column :pizzas, :tags, :tags_migration

create_table :tags do |t|
  t.string :name
  t.integer :count
  t.timestamps
end

create_join_table :tags, :pizzas do |t|
  t.index [:tag_id, :pizza_id]
end

Pizza.all.each do |pizza|
  pizza_tags = pizza.tags_migration
  unless pizza_tags.empty?
    pizza_tags_array = pizza_tags.split(', ')
    pizza_tags_array.each do |tag|
      t = Tag.find_by(name: tag)
      if t.nil?
        t = Tag.new
        t.name = tag
        t.count = 1
      else
        t.count = t.count + 1
      end
      t.pizzas << pizza
      t.save
      pizza.tags << t
      pizza.save
    end
  end
  puts "pizza n" + pizza.id.to_s
end
end

我认为这段代码不应该花那么长时间(我大约有2000条条目)

2 个答案:

答案 0 :(得分:5)

由于Pizza.all,您似乎在内存中占有相当大的比例。一个简单的性能好处就是将Pizza.all.each更改为Pizza.find_each

答案 1 :(得分:1)

  1. @codenamev关于find_each的要点
  2. 您在Tag.find_by(name:tag)中有n + 1个查询
  3. 还有这里

-

t.pizzas << pizza
t.save
pizza.tags << t
pizza.save

您可以在事务中运行整个过程以一次提交所有更改(但可能会导致锁定)

我不确定实现的细节,但是上面的代码可能会减少一半,因为t.pizzas << pizza将同时分配两个模型。 has_many ... :through关联应对此进行处理

另外,请考虑将更新部分移到迁移之外,因为它将锁定数据库一段时间