簡體   English   中英

避免在大型數據集中進行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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM