Очень медленная миграция - PullRequest
       0

Очень медленная миграция

0 голосов
/ 07 декабря 2018

Моя последняя миграция выполняется очень медленно (600 секунд), несмотря на то, что она мало что делает

У меня есть модель, которая содержит теги в строковом формате, разделенные запятыми, например:

Модель.tags = "TAG1, TAG2, TAG3"

Я хочу создать новую модель тега, которая имеет отношение 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 голосов
/ 07 декабря 2018
  1. Хороший комментарий @codenamev о find_each
  2. У вас есть n + 1 запрос в Tag.find_by (name: tag)
  3. А также здесь

-

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

Вы можете запустить все это в транзакции, чтобы зафиксировать все изменения сразу (но это может вызвать блокировки)

Я не уверен насчетдетали реализации, но приведенный выше код можно было бы разрезать пополам, так как t.pizzas << pizza назначит обе модели.has_many ... :through Ассоциация должна обрабатывать это

Кроме того, рассмотрите возможность перемещения компонента обновления за пределы миграции, так как он на некоторое время заблокирует базу данных

0 голосов
/ 07 декабря 2018

Похоже, что вы можете держать немного в памяти (из-за Pizza.all).Простой выигрыш в производительности - изменить Pizza.all.each на Pizza.find_each

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...