避免在大数据集中进行n+1查询

8zzbczxx  于 2021-06-19  发布在  Mysql
关注(0)|答案(1)|浏览(258)

我有一个用新属性值更新现有记录的迁移。这个模型叫做“myrecord”。它在数据库中有数百万条记录,新的unit\u id列为null。我想用一个特定值更新unit\u id列:

MyRecord.find_each do |record|
  unit_id = Unit.calculate_unit_from_old_columns(record.legacy_column_1, record.legacy_column_2).first.id
  record.update unit_id: unit_id
end

这会创建大量n+1查询:

SELECT units.* FROM units WHERE units.item_1 = 'Electronics' AND units.item_2 = 'Auto' 
UPDATE my_records SET unit_id='43' WHERE legacy_column_1 = 'Legacy Electronics' AND legacy_column_2 = 'Legacy Auto';

其中一些n+1查询是重复的。我在日志中看到了很多:

SELECT units.* FROM units WHERE units.item_1 = 'Electronics' AND units.item_2 = 'Auto' 
SELECT units.* FROM units WHERE units.item_1 = 'Electronics' AND units.item_2 = 'Auto'

我很熟悉快速加载。但当运行此迁移来更新现有数据时,还没有关联。所以我不能这么做:

record.includes(:unit)

如何消除n+1查询并缓存查询,以便在重复查询时不会再次命中数据库?

huwehgph

huwehgph1#

使用一个简单的查询,如果运行时间过长,可以考虑对其进行批处理:

MyRecord.connection.execute(
  "UPDATE my_records, units 
   SET unit_id = units.id 
   WHERE units.item_1 = legacy_column_1 AND units.item_2 = legacy_column_2"
)

相关问题