我有一个非常简单的集合,除了_id之外没有索引。每个文档都包含一个数组字段mies
。当前集合的大小约为1亿,我可以在探查器中看到以下异常:
{
"op": "update",
"ns": "DB.links",
"command": {
"q": {
"_id": "f1b54f37-7f92-4e75-9ec6-5329349ce792_eb370c8a-6f33-4989-aa59-a26e1c9df46c"
},
"u": {
"$push": {
"mies": {
"$each": [
{
"$oid": "5e39d07bec34b8000e7f86b7"
}
]
}
}
},
"multi": true,
"upsert": true
},
"keysExamined": 0,
"docsExamined": 0,
"nMatched": 0,
"nModified": 0,
"upsert": true,
"keysInserted": 1,
"numYield": 0,
"locks": {
"Global": {
"acquireCount": {
"r": 2,
"w": 2
}
},
"Database": {
"acquireCount": {
"w": 2
},
"acquireWaitCount": {
"w": 1
},
"timeAcquiringMicros": {
"w": 19486143
}
},
"Collection": {
"acquireCount": {
"w": 1
}
},
"oplog": {
"acquireCount": {
"w": 1
}
}
},
"millis": 19490,
"planSummary": "IDHACK",
"execStats": {
"stage": "UPDATE",
"nReturned": 0,
"executionTimeMillisEstimate": 0,
"works": 2,
"advanced": 0,
"needTime": 1,
"needYield": 0,
"saveState": 0,
"restoreState": 0,
"isEOF": 1,
"invalidates": 0,
"nMatched": 0,
"nWouldModify": 0,
"nInvalidateSkips": 0,
"wouldInsert": true,
"fastmodinsert": false,
"inputStage": {
"stage": "IDHACK",
"nReturned": 0,
"executionTimeMillisEstimate": 0,
"works": 1,
"advanced": 0,
"needTime": 0,
"needYield": 0,
"saveState": 0,
"restoreState": 0,
"isEOF": 1,
"invalidates": 0,
"keysExamined": 0,
"docsExamined": 0
}
}
}
如您所见,一个带有单个$ push的简单upsert花费了19秒。我相信大部分时间都在这里度过:
"timeAcquiringMicros": {
"w": 19486143
}
我应该检查什么?如何提高性能?
[MongoDB使用B-tree算法来索引操作,例如:插入,搜索,删除。
Algorithm Average Worst case
Space O(n) O(n)
Search O(log n) O(log n)
Insert O(log n) O(log n)
Delete O(log n) O(log n)
MongoDB需要向下钻取索引以查找值。由于_id
是唯一的默认索引,因此MongoDB需要进行27
迭代才能在最坏的情况下查找文档(134.217.728
[〜19sec]为2 27,268.435.456
为2 28 [〜21sec],等等...)
您可以通过创建search
来改善compound index
操作,但是会因MongoDB需要更新insert
索引+ _id
而对cound index
造成不利影响。