Mongo Query计划人员如何选择索引

时间:2018-08-21 19:47:53

标签: mongodb indexing

Mongo版本:3.4.3-10-g865d2fb

我有这样的请求:

db.getCollection('c_zop_operations').find({

     "a":{
        "$in":[
           "O",
           "S",
           "P"
        ]
     },
     "$or":[
        {
           "b":"008091",
           "c":"1187",
           "d":"F",
           "e":ISODate("2018-07-22T22:00:00.000Z")
        },
... x 39 elements in $or statement
     ]
}).explain("executionStats")

请求在16秒内进行解释并返回以下结果:

155769文档在索引中解析!!!

{
"queryPlanner" : {
    "plannerVersion" : 1,
    ...
    "indexFilterSet" : false,
    "parsedQuery" : {
      ...
    },
    "winningPlan" : {
        "stage" : "FETCH",
        "filter" : {
            "$or" : [ 
                {
                    "$and" : [ 
                        {
                            "c" : {
                                "$eq" : "1187"
                            }
                        }, 
                        {
                            "d" : {
                                "$eq" : "F"
                            }
                        }, 
                        {
                            "b" : {
                                "$eq" : "008091"
                            }
                        }, 
                        {
                            "e" : {
                                "$eq" : ISODate("2018-07-22T22:00:00.000Z")
                            }
                        }
                    ]
                }, 
                x 39 times
                ...
        },
        "inputStage" : {
            "stage" : "IXSCAN",
            "keyPattern" : {
                "a" : 1
            },
            "indexName" : "a",
            "isMultiKey" : false,
            "isUnique" : false,
            "isSparse" : false,
            "isPartial" : false,
            "indexVersion" : 1,
            "direction" : "forward",
            "indexBounds" : {
                "a" : [ 
                    "[\"O\", \"O\"]", 
                    "[\"P\", \"P\"]", 
                    "[\"S\", \"S\"]"
                ]
            }
        }
    },
    "rejectedPlans" : [ 
    ...
    ]
},
"executionStats" : {
    "executionSuccess" : true,
    "nReturned" : 0,
    "executionTimeMillis" : 16010,
    "totalKeysExamined" : 155769,
    "totalDocsExamined" : 155769,
    ...
}
...
}

在我的收藏集中,我有很多索引(65),并且我的收藏包含300万份文档。

这里只有两个索引使我感兴趣:

aIndex : { "a" : 1 }

还有

beIndex: { "b" : 1,  "e" : 1 }

默认情况下,mongo使用{“ a”:1},请求将花费16秒。 如果我使用hint(beIndex),则请求将花费0,011秒,并且totalKeysExamined = 0和totalDocsExamined = 0。

为什么MongoDB不使用更有效的beIndex?

1 个答案:

答案 0 :(得分:0)

此行为是一个已知的错误。参见SERVER-13732。该问题已在MongoDB 3.6中修复。

作为一种解决方法,将a上的顶级过滤器分配到每个$ or子句中应使查询计划者可以做出更好的索引选择。