0
点赞
收藏
分享

微信扫一扫

关于设计mongodb索引,涉及到内存排序问题解决


关于设计mongodb索引,涉及到内存排序问题解决

查询脚本如下:


db.QuickReplyTemplate.find({
"sceneKey": "responseMsg",
"termId": 1,
"isDelete": false
}).sort({
"updatedOn": 1
}).explain("executionStats");


 

很简单一个查询,然后我们需要设计两个索引,看看mongodb执行器对这两个索引如何选择优化?

db.getCollection("QuickReplyTemplate").createIndex({
sceneKey: NumberInt("1"),
termId: NumberInt("1"),
isDelete: NumberInt("1")
}, {
name: "idx_QuickReplyTemplate__sceneKey_1_termId_1_isDelete_1"
});


db.getCollection("QuickReplyTemplate").createIndex({
sceneKey: NumberInt("1"),
termId: NumberInt("1"),
isDelete: NumberInt("1"),
updatedOn: NumberInt("1")
}, {
name: "idx_QuickReplyTemplate__sceneKey_1_termId_1_isDelete_1_updatedOn_1"
});


 

两个很简单是索引,并且区别很明显,后者多了一个updateOn参数,然后这个参数就是排序参数,我们看看执行计划

// 1
{
"queryPlanner": {
"plannerVersion": NumberInt("1"),
"namespace": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx.QuickReplyTemplate",
"indexFilterSet": false,
"parsedQuery": {
"$and": [
{
"isDelete": {
"$eq": false
}
},
{
"sceneKey": {
"$eq": "responseMsg"
}
},
{
"termId": {
"$eq": 1
}
}
]
},
"winningPlan": {
"stage": "FETCH",
"inputStage": {
"stage": "IXSCAN",
"keyPattern": {
"sceneKey": NumberInt("1"),
"termId": NumberInt("1"),
"isDelete": NumberInt("1"),
"updatedOn": NumberInt("1")
},
"indexName": "idx_QuickReplyTemplate__sceneKey_1_termId_1_isDelete_1_updatedOn_1",
"isMultiKey": false,
"multiKeyPaths": {
"sceneKey": [ ],
"termId": [ ],
"isDelete": [ ],
"updatedOn": [ ]
},
"isUnique": false,
"isSparse": false,
"isPartial": false,
"indexVersion": NumberInt("2"),
"direction": "forward",
"indexBounds": {
"sceneKey": [
"[\"responseMsg\", \"responseMsg\"]"
],
"termId": [
"[1.0, 1.0]"
],
"isDelete": [
"[false, false]"
],
"updatedOn": [
"[MinKey, MaxKey]"
]
}
}
},
"rejectedPlans": [
{
"stage": "SORT",
"sortPattern": {
"updatedOn": 1
},
"inputStage": {
"stage": "SORT_KEY_GENERATOR",
"inputStage": {
"stage": "FETCH",
"inputStage": {
"stage": "IXSCAN",
"keyPattern": {
"sceneKey": NumberInt("1"),
"termId": NumberInt("1"),
"isDelete": NumberInt("1")
},
"indexName": "idx_QuickReplyTemplate__sceneKey_1_termId_1_isDelete_1",
"isMultiKey": false,
"multiKeyPaths": {
"sceneKey": [ ],
"termId": [ ],
"isDelete": [ ]
},
"isUnique": false,
"isSparse": false,
"isPartial": false,
"indexVersion": NumberInt("2"),
"direction": "forward",
"indexBounds": {
"sceneKey": [
"[\"responseMsg\", \"responseMsg\"]"
],
"termId": [
"[1.0, 1.0]"
],
"isDelete": [
"[false, false]"
]
}
}
}
}
}
]
},
"executionStats": {
"executionSuccess": true,
"nReturned": NumberInt("0"),
"executionTimeMillis": NumberInt("12"),
"totalKeysExamined": NumberInt("0"),
"totalDocsExamined": NumberInt("0"),
"executionStages": {
"stage": "FETCH",
"nReturned": NumberInt("0"),
"executionTimeMillisEstimate": NumberInt("0"),
"works": NumberInt("2"),
"advanced": NumberInt("0"),
"needTime": NumberInt("0"),
"needYield": NumberInt("0"),
"saveState": NumberInt("0"),
"restoreState": NumberInt("0"),
"isEOF": NumberInt("1"),
"invalidates": NumberInt("0"),
"docsExamined": NumberInt("0"),
"alreadyHasObj": NumberInt("0"),
"inputStage": {
"stage": "IXSCAN",
"nReturned": NumberInt("0"),
"executionTimeMillisEstimate": NumberInt("0"),
"works": NumberInt("1"),
"advanced": NumberInt("0"),
"needTime": NumberInt("0"),
"needYield": NumberInt("0"),
"saveState": NumberInt("0"),
"restoreState": NumberInt("0"),
"isEOF": NumberInt("1"),
"invalidates": NumberInt("0"),
"keyPattern": {
"sceneKey": NumberInt("1"),
"termId": NumberInt("1"),
"isDelete": NumberInt("1"),
"updatedOn": NumberInt("1")
},
"indexName": "idx_QuickReplyTemplate__sceneKey_1_termId_1_isDelete_1_updatedOn_1",
"isMultiKey": false,
"multiKeyPaths": {
"sceneKey": [ ],
"termId": [ ],
"isDelete": [ ],
"updatedOn": [ ]
},
"isUnique": false,
"isSparse": false,
"isPartial": false,
"indexVersion": NumberInt("2"),
"direction": "forward",
"indexBounds": {
"sceneKey": [
"[\"responseMsg\", \"responseMsg\"]"
],
"termId": [
"[1.0, 1.0]"
],
"isDelete": [
"[false, false]"
],
"updatedOn": [
"[MinKey, MaxKey]"
]
},
"keysExamined": NumberInt("0"),
"seeks": NumberInt("1"),
"dupsTested": NumberInt("0"),
"dupsDropped": NumberInt("0"),
"seenInvalidated": NumberInt("0")
}
}
},
"serverInfo": {
"host": "localhost.localdomain",
"port": NumberInt("50000"),
"version": "4.0.1",
"gitVersion": "54f1582fc6eb01de4d4c42f26fc133e623f065fb"
},
"ok": 1
}


 

 

开始分析:

关于设计mongodb索引,涉及到内存排序问题解决_mongodb

 

可以看到,它选择了后者,并且:检出文档、然后有进行了索引扫描,基本上可以理解为最优了。

 

然后我们看看它排除了哪些索引?

关于设计mongodb索引,涉及到内存排序问题解决_mongodb_02

 

第一步可以看出,进行了内存排序(SORT);虽然,我们可以看出,他走了索引,但是索引命中的数据,又进行了内存排序。那么产生内存排序的危害,我们就不细聊了。可以度娘;

举报

相关推荐

0 条评论