[英]How to combine these two queries into one optimized query to avoid a Select N+1
[英]Avoid N+1 query in large data set
我有一個遷移,它使用新的屬性值更新現有記錄。 該模型稱為“ MyRecord”。 它在數據庫中具有數百萬條記錄,其中新的unit_id列為null。 我想使用特定值更新unit_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個查詢並緩存該查詢,以便在重復查詢時它不會再次命中數據庫?
使用簡單的查詢,如果運行時間過長,您可以考慮對其進行批處理:
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"
)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.