[英]MongoDB - performance and collection size
關於集合大小和查詢性能,我有一個問題–
有2個dbs – DB1和DB2。 DB1有1個集合,這是此集合stats()的輸出–
{
…
"count" : 2085217,
"size" : 17048734192,
"avgObjSize" : 8176,
"capped" : false,
"nindexes" : 3,
"indexDetails" : {},
"totalIndexSize" : 606299456,
"indexSizes" : {
"_id_" : 67664576,
"id_1" : 284165056,
"id_2" : 254469824
},
…
}
使用索引id_1對該集合的查詢將在0.012秒內返回。 這是explain()的輸出-
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 1,
"executionTimeMillis" : 0,
"totalKeysExamined" : 1,
"totalDocsExamined" : 1,
….
"indexName" : "id_1",
}
在DB2中,我有4個集合,這是DB2上的統計信息的輸出–
{
…
"collections" : 4,
"objects" : 152655935,
"avgObjSize" : 8175.998307514215,
"dataSize" : 1248114666192,
"storageSize" : 1257144933456,
"indexes" : 12,
"indexSize" : 19757688272,
"fileSize" : 1283502112768,
…
}
使用索引(我通過explain()確認)對DB2中的任何集合進行查詢所花費的時間至少比對DB1進行的上一查詢所花費的時間至少要長兩倍。
既然mongo應該很好地擴展,為什么會有這個差異? 我讀到mongodb將所有索引加載到內存中,並且由於DB2的容量比DB1大,這就是為什么它需要更長的時間嗎?
任何見解將大有幫助。 謝謝。
編輯1:重新添加更多信息。 集合定義,索引定義和執行的查詢...
所有的集合(在兩個數據庫中)都包含相同的字段。 它們之間只有文檔的值和大小不同。
而且,這是相關的索引-
"1" : {
"v" : 1,
"unique" : true,
"key" : {
"id" : 1
},
"name" : "id_1",
"ns" : "ns.coll1"
}
而且,這是id字段的樣子:
"_id" : ObjectId("55f9b6548aefbce6b2fa2fac"),
"id" : {
"pid" : {
"f1" : "val1",
"f2" : "val2"
}
},
而且,這是一個示例查詢-
db.coll1.find({id:{pid:{f1:"val1",f2:"val2"}}})
編輯2:這是有關硬盤和RAM的更多信息-
$ free -m
total used free shared buff/cache available
Mem: 386758 3750 1947 25283 381060 355675
Swap: 131071 3194 127877
硬盤約為3.5T,其中已經使用了2.9T。
MongoDB很好地擴展。 事實是,它被設計為水平縮放,而不是垂直縮放。 這意味着,如果您的數據庫包含大量數據,則應將這些集合分片,以實現更好的並行化。
關於查詢時間的差異,我認為您的分析不是結論性的。 這些數據庫可能位於不同的機器上(具有不同的規格)。 假設硬件相同,則DB2顯然在其集合上保存了更多文檔,並且兩個DB上的文檔大小都不相同。 相同的查詢可以返回不同大小的數據集。 這將不可避免地對數據序列化和其他低級方面產生影響。 除非您以更可控的設置來分析查詢,否則我認為您的結果將是可預期的。
如果您在文檔上使用DRef,請當心。 它可能的Mongo會自動取消引用它們; 這意味着更多的數據需要序列化和開銷。
嘗試使用limit
規范運行相同的查詢。 您已將索引定義為唯一,但我不知道一旦找到值,Mongo是否會自動使遍歷停止索引遍歷。 檢查db.coll1.find({id:{pid:{f1:"val1",f2:"val2"}}})
和db.coll1.find({id:{pid:{f1:"val1",f2:"val2"}}}).limit(1)
運行。
看一下嵌入式字段上的 索引和嵌入式文檔上的索引 。 嵌入式文檔似乎甚至會削弱額外的開銷。
最后,如果您的文檔沒有嵌入的文檔,而只有嵌入的字段(似乎是這種情況),則可以更具體地定義索引。 創建該索引
db.coll1.createIndex({"id.pid.f1": 1, "id.pid.f2": 1}, {unique: true})
並再次運行查詢。 如果該索引不能提高性能,那么我相信您已正確完成了所有操作,可能是時候開始分片了 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.