我的最新迁移运行得很慢(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条条目)
答案 0 :(得分:5)
由于Pizza.all
,您似乎在内存中占有相当大的比例。一个简单的性能好处就是将Pizza.all.each
更改为Pizza.find_each
答案 1 :(得分:1)
find_each
的要点-
t.pizzas << pizza
t.save
pizza.tags << t
pizza.save
您可以在事务中运行整个过程以一次提交所有更改(但可能会导致锁定)
我不确定实现的细节,但是上面的代码可能会减少一半,因为t.pizzas << pizza
将同时分配两个模型。 has_many ... :through
关联应对此进行处理
另外,请考虑将更新部分移到迁移之外,因为它将锁定数据库一段时间