插入图片就报错,profiler在生产也截不出来,只能口述一下请各位大佬解惑了。
目前有一个索引A是{‘a’:1,’duration’:1,’time’:-1},还有一个索引B是{‘a’:1,’c’:1,’d’:1,’time’:-1}以及C是{‘a’:1,’e’:1,’f’:1,’g’:1,’time’:-1}
此时我的查询语句为find({‘a’:’1234′,’duration’:{$gte:200},’time’:{$gte:ISODate(‘2022-01-01’)}}).sort({‘time’:-1})
我的预期是使用索引A,但是实际上使用的B或者C。请问各位大佬这是因为什么呢
我的查询语句是
db.collection.find({“business_fields.center_id”:”8629″,
“recordDuration”:{$gte:600},
“business_fields.dial_starttime”:{$gte:ISODate(“2021-12-01”)}
}).sort({“business_fields.dial_starttime”:-1})
WinningPlan命中的索引是
{“business_fields.center_id”:1,
“business_fields.list_type”:1,
“business_fields.list_detail”:1,
“business_fields.dial_starttime”: -1}
RejectedPlan命中的索引是
{“business_fields.center_id”:1,
“recordDuration”:1,
“business_fields.dial_starttime”: -1}
涉及字段的数据结构是这样的
{”xxx”:”xxx”,
“recodDuration”: 996,
“business_fields”:{“xxx”:”xxx”,
“center_id”:”8629″,
“dial_starttime”:ISODate(“2021-12-25”)
“list_type”:”XIV”,
“list_detail”:”XII”,
“XXX”:”XXX”
},
“XXX”:”XXX”
}
针对2个索引,都存在被选中的情况,主要跟数据分布有一定关系。“business_fields.center_id”等于一个值,如果匹配数据量相对较少的情况,使用2个索引都可以。执行计划在选择的时候,会同时会后选的索引同时执行,优先返回的结果的索引会被选中。如果想要规避这种情况:
1、建议创建ESR索引:{“business_fields.center_id”:1,“business_fields.dial_starttime”: 1,“recordDuration”:1},这个通常是性能好于如下这个。
{“business_fields.center_id”:1,
“recordDuration”:1,
“business_fields.dial_starttime”: -1}
2、使用hint来强制索引。
WinningPlan命中的索引是
{“business_fields.center_id”:1,
“business_fields.list_type”:1,
“business_fields.list_detail”:1,
“business_fields.dial_starttime”: -1}
RejectedPlan命中的索引是
{“business_fields.center_id”:1,
“recordDuration”:1,
“business_fields.dial_starttime”: -1}
以下是模拟的执行计划:
db.xiaoxu.find({“business_fields.center_id”:”8629″,”recodDuration”:{$gte:600},”business_fields.dial_starttime”:{$gte:ISODate(“2021-12-01”)}}).sort({“business_fields.dial_starttime”:-1}).explain()
{
“queryPlanner” : {
“mongosPlannerVersion” : 1,
“winningPlan” : {
“plannerVersion” : 1,
“namespace” : “test.xiaoxu”,
“indexFilterSet” : false,
“parsedQuery” : {
“$and” : [
{
“business_fields.center_id” : {
“$eq” : “8629”
}
},
{
“business_fields.dial_starttime” : {
“$gte” : ISODate(“2021-12-01T00:00:00Z”)
}
},
{
“recodDuration” : {
“$gte” : 600
}
}
]
},
“queryHash” : “C95528B5”,
“planCacheKey” : “888D6763”,
“winningPlan” : {
“stage” : “FETCH”,
“inputStage” : {
“stage” : “IXSCAN”,
“keyPattern” : {
“business_fields.center_id” : 1,
“business_fields.dial_starttime” : 1,
“recodDuration” : 1
},
“indexName” : “business_fields.center_id_1_business_fields.dial_starttime_1_recodDuration_1”,
“isMultiKey” : false,
“multiKeyPaths” : {
“business_fields.center_id” : [ ],
“business_fields.dial_starttime” : [ ],
“recodDuration” : [ ]
},
“isUnique” : false,
“isSparse” : false,
“isPartial” : false,
“indexVersion” : 2,
“direction” : “backward”,
“indexBounds” : {
“business_fields.center_id” : [
“[\”8629\”, \”8629\”]”
],
“business_fields.dial_starttime” : [
“[new Date(9223372036854775807), new Date(1638316800000)]”
],
“recodDuration” : [
“[inf.0, 600.0]”
]
}
}
},
“rejectedPlans” : [
{
“stage” : “SORT”,
“sortPattern” : {
“business_fields.dial_starttime” : -1
},
“memLimit” : 104857600,
“type” : “simple”,
“inputStage” : {
“stage” : “FETCH”,
“filter” : {
“recodDuration” : {
“$gte” : 600
}
},
“inputStage” : {
“stage” : “IXSCAN”,
“keyPattern” : {
“business_fields.center_id” : 1,
“business_fields.list_type” : 1,
“business_fields.list_detail” : 1,
“business_fields.dial_starttime” : -1
},
“indexName” : “business_fields.center_id_1_business_fields.list_type_1_business_fields.list_detail_1_business_fields.dial_starttime_-1”,
“isMultiKey” : false,
“multiKeyPaths” : {
“business_fields.center_id” : [ ],
“business_fields.list_type” : [ ],
“business_fields.list_detail” : [ ],
“business_fields.dial_starttime” : [ ]
},
“isUnique” : false,
“isSparse” : false,
“isPartial” : false,
“indexVersion” : 2,
“direction” : “forward”,
“indexBounds” : {
“business_fields.center_id” : [
“[\”8629\”, \”8629\”]”
],
“business_fields.list_type” : [
“[MinKey, MaxKey]”
],
“business_fields.list_detail” : [
“[MinKey, MaxKey]”
],
“business_fields.dial_starttime” : [
“[new Date(9223372036854775807), new Date(1638316800000)]”
]
}
}
}
},
{
“stage” : “FETCH”,
“inputStage” : {
“stage” : “SORT”,
“sortPattern” : {
“business_fields.dial_starttime” : -1
},
“memLimit” : 104857600,
“type” : “default”,
“inputStage” : {
“stage” : “IXSCAN”,
“keyPattern” : {
“business_fields.center_id” : 1,
“recodDuration” : 1,
“business_fields.dial_starttime” : -1
},
“indexName” : “business_fields.center_id_1_recodDuration_1_business_fields.dial_starttime_-1”,
“isMultiKey” : false,
“multiKeyPaths” : {
“business_fields.center_id” : [ ],
“recodDuration” : [ ],
“business_fields.dial_starttime” : [ ]
},
“isUnique” : false,
“isSparse” : false,
“isPartial” : false,
“indexVersion” : 2,
“direction” : “forward”,
“indexBounds” : {
“business_fields.center_id” : [
“[\”8629\”, \”8629\”]”
],
“recodDuration” : [
“[600.0, inf.0]”
],
“business_fields.dial_starttime” : [
“[new Date(9223372036854775807), new Date(1638316800000)]”
]
}
}
}
},
{
“stage” : “FETCH”,
“inputStage” : {
“stage” : “IXSCAN”,
“keyPattern” : {
“business_fields.center_id” : 1,
“business_fields.dial_starttime” : -1,
“recodDuration” : 1
},
“indexName” : “business_fields.center_id_1_business_fields.dial_starttime_-1_recodDuration_1”,
“isMultiKey” : false,
“multiKeyPaths” : {
“business_fields.center_id” : [ ],
“business_fields.dial_starttime” : [ ],
“recodDuration” : [ ]
},
“isUnique” : false,
“isSparse” : false,
“isPartial” : false,
“indexVersion” : 2,
“direction” : “forward”,
“indexBounds” : {
“business_fields.center_id” : [
“[\”8629\”, \”8629\”]”
],
“business_fields.dial_starttime” : [
“[new Date(9223372036854775807), new Date(1638316800000)]”
],
“recodDuration” : [
“[600.0, inf.0]”
]
}
}
}
]
}
]
}
},
非常感谢您的解答,受益良多