- Rails v5.2.4.3
- 紅寶石 v2.3.3
我們有一個 Workspace 表和一個 WorkspaceGroup 表,這兩個表之間通過一個名為 WorkspaceGroupAssociation 的連接表建立了多對多關系(作業區就像我們域模型中的一個專案)。所以一個專案可以屬于多個組,一個組可以有多個專案。
我們有一些擁有數千個專案的組,在我們的可觀察性工具中,我們最近注意到以下舊代碼非常慢(請注意,以下代碼是該方法的簡化版本):
class WorkspaceGroup < ApplicationRecord
def add_workspaces(workspace_ids)
self.workspace_ids |= workspace_ids
end
end
我們有一個小組,上面已經有大約 5,000 個作業區,添加這些新的作業區 ID 需要 2 分鐘以上的時間。
我們最初的方法是更改self.workspace_ids |= workspace_ids為self.workspace_ids = workspace_ids,但這在性能方面根本沒有改變。然后我們嘗試了以下方法,效果很好:
def add_workspaces(workspace_ids)
existing_workspaces = self.workspaces
workspaces_to_add = Workspace.where(id: workspace_ids) - existing_workspaces
workspaces_to_add.each do |workspace|
self.workspaces << workspace
end
end
上面代碼的作者說,性能提升是因為我們沒有在新代碼中實體化Workspace模型的5000個新實體,而是在舊代碼中。
我很好奇為什么舊代碼是這樣,但新代碼不是。為什么會self.workspace_ids =導致實體化數千個新的 ActiveRecord 實體,但self.workspaces <<不會?
uj5u.com熱心網友回復:
為 Rails 中的集合執行此操作
def (other)
Collection.new(to_a other.to_a)
end
雖然<<這...
def <<(*records)
proxy_association.concat(records) && self
end
我的猜測是,創建一個新的Collection操作比進行連接更昂貴。
https://api.rubyonrails.org/v6.1.4/classes/ActiveRecord/Associations/CollectionProxy.html#method-i-3C-3C
https://api.rubyonrails.org/classes/Rails/Initializable/Collection.html#method-i-2B
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/376642.html
上一篇:Rails活動記錄中的自參考問題
下一篇:如何從物件創建陣列并只保留正值?
