![](/img/trans.png)
[英]Speed and performance optimisation problem: Multiple database model vs single database
[英]Mongo optimisation: query performance vs database structure
上下文:連接到MongoDB 4.0服務器的NodeJs(meteorjs)應用程序
我有一組經常計算的數據,需要存儲時間,然后才能從我的應用訪問特定的數據集。 該集合是一個由12 000個對象組成的數組,最終權重約為3MB(通過僅使用一組數據的Collection上的MongoDB集合統計數據來衡量:大小:3.3 MB;計數:12964)。 它與一些計算參數有關。 我需要使用查詢來檢索集合。
我必須在兩種數據庫結構之間進行選擇:
選項1:一個集合存儲一個具有ID的計算引用(將其命名為ReferenceCollection
),另一個集合將每個計算的所有12000個對象存儲為單個文檔,一個referenceId指向之前創建的ID。
這是一個示意圖:
ReferenceCollection :
|--- _id: ObjectId("a")
|--- computation : "my reference"
ResultCollection :
|--- _id: ObjectId("b")
|--- referenceId : ObjectId("a")
|--- fieldResut1 : data
.
.
|--- fieldResut20 : data
要檢索該集合,我將使用計算參數在第一個集合中查詢referenceId,然后使用參考ID查詢第二個集合以獲取12000個文檔。
let reference = ReferenceCollection.findOne({computation: "my reference"}) // this is lightweight
let results = ResultCollection.find({referenceId: reference._id}) // this search for the 12 000 results
選項2:單個集合存儲計算引用,其中包含帶有包含內部數據數組的鍵的計算引用
這是一個示意圖:
ResultCollection :
|--- _id: ObjectId("b")
|--- computation : "my reference"
|--- result : Array(
|--- fieldResut1 : data
.
.
|--- fieldResut20 : data
)
要檢索該集合,我將只對我的計算參數進行一次查詢,以獲得包含所有數據的單個文檔。
問題:第一個選項遇到性能問題:從MongoDB桌面客戶端(studio 3T)查詢和檢索所有12000文檔非常慢:在我的設置中為3秒。 第二個選項只需1秒鍾即可檢索(這些時間包括數據下載)。 這導致我的應用在獲取數據時需要等待很多時間。
返回游標時,從服務器上的mongoshell進行查詢的速度非常快(選項1約為20毫秒)。
您可以確認選項2是存儲此數據的好選擇嗎?
關於數據結構,我還有其他選擇嗎?
我在單個節點上運行MongoDB。 您是否認為設置副本集可以幫助提高讀取性能?
在這種情況下,您可能會發現差異主要是由於必須執行兩個與您的網絡最相關的連接/查詢。
例如,如果在事務集合中引用了用戶集合,則將使用選項1。
這樣的想法是,如果需要連接兩個集合,則只有在連接集合將被多次引用且文檔復雜的情況下,才進行連接。
如果僅僅是擁有一個名稱集合,然后在另一個集合中引用它,那是錯誤的。
如果您需要連接兩個Mongo集合,請考慮使用聚合,這樣與需要執行多個查詢相比,Mongo服務器可以一擊獲得數據。
編輯:
為了讓您對性能有所了解,目前的第一個選擇將花費兩倍的時間,純粹是因為它必須連接兩次。 如果相同的查詢經常發生,那么您確實會發現性能下降毫無益處(除非“ computation”(計算)字段發生了很大的變化,否則可能是合理的)。 如果您使用的是聚合,那么您將不會看到任何性能下降,因為它被視為單個連接。
選項二只是一次查找,然后是返回數組數據所花費的時間。 因此,在大多數情況下,使用聚合時與選項1相同。
還應考慮到數組由復雜對象組成時可能是瓶頸。 理想情況下,您應該避免使用數組並將其展平為帶有字段的單個文檔。 這樣,當您執行查詢時,可以設置要返回的字段,從而不返回不需要的字段。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.