解释显示快速执行时间,但运行查询永远不会返回

时间:2017-05-09 09:29:59

标签: mongodb mongodb-query explain

我有一个似乎永远不会返回的查询。 当我在该查询上运行explain时,它显示我{27}的executionStats.executionTimeMillis,并且初始输入阶段为IXSCAN,仅应返回4个对象。 我已经确认查询输入阶段查询只返回4个结果。

这是我的疑问:

{"$or":[
    {"field1.key":{"$in":["name1","name2",/^prefix.*suffix$/]},"field2.key":"foobar"},
    {"field1.key":{"$in":["name1","name2",/^prefix.*suffix$/]},"field3.key":"foobar"}
]}

这是explain({ verbose : "executionStats" })输出(对于长粘贴感到抱歉):

{
    "queryPlanner" : {
        "mongosPlannerVersion" : 1,
        "winningPlan" : {
            "stage" : "SHARD_MERGE",
            "shards" : [ 
                {
                    "shardName" : "...",
                    "plannerVersion" : 1,
                    "indexFilterSet" : false,
                    "parsedQuery" : { ... },
                    "winningPlan" : {
                        "stage" : "SUBPLAN",
                        "inputStage" : {
                            "stage" : "OR",
                            "inputStages" : [ 
                                {
                                    "stage" : "FETCH",
                                    "filter" : {"field1.key":{"$in":["name1","name2",/^prefix.*suffix$/]},
                                    "inputStage" : {
                                        "stage" : "IXSCAN",
                                        "keyPattern" : { "field3.key" : 1.0 },
                                        "indexName" : "field3.key_1",
                                        "isMultiKey" : true,
                                        "isUnique" : false,
                                        "isSparse" : false,
                                        "isPartial" : false,
                                        "indexVersion" : 1,
                                        "direction" : "forward",
                                        "indexBounds" : {
                                            "field3.key" : [ "[\"foobar\", \"foobar\"]" ]
                                        }
                                    }
                                }, 
                                {
                                    "stage" : "FETCH",
                                    "filter" : {"field1.key":{"$in":["name1","name2",/^prefix.*suffix$/]},
                                    "inputStage" : {
                                        "stage" : "IXSCAN",
                                        "keyPattern" : { "field2.key" : 1.0 },
                                        "indexName" : "field2.key_1",
                                        "isMultiKey" : true,
                                        "isUnique" : false,
                                        "isSparse" : false,
                                        "isPartial" : false,
                                        "indexVersion" : 1,
                                        "direction" : "forward",
                                        "indexBounds" : {
                                            "field2.key" : [ "[\"foobar\", \"foobar\"]" ]
                                        }
                                    }
                                }
                            ]
                        }
                    },
                    "rejectedPlans" : []
                }, 
                ...
                // same plan for the 3 other shards
                ...
            ]
        }
    },
    "executionStats" : {
        "nReturned" : 0,
        "executionTimeMillis" : 27,
        "totalKeysExamined" : 4,
        "totalDocsExamined" : 4,
        "executionStages" : {
            "stage" : "SHARD_MERGE",
            "nReturned" : 0,
            "executionTimeMillis" : 27,
            "totalKeysExamined" : 4,
            "totalDocsExamined" : 4,
            "totalChildMillis" : NumberLong(63),
            ...
            // execution times for each shard
            ...
        },
        "allPlansExecution" : []
    },
    "ok" : 1.0
}

更新

尽管explain提到"field2.key"的{​​{1}}的第一部分和$or的第二部分"field3.key",但似乎看$or它显示: db.currentOp().inprog 所以它为其中一个"planSummary": "IXSCAN { field1.key: 1.0 }, IXSCAN { field3.key: 1.0 }"部分选择了错误的索引,从而使查询扫描了大量的文档。

  1. 知道为什么$or正确获取索引,但查询本身没有?
  2. 使用explain时,我们如何hint mongo使用正确的索引?

0 个答案:

没有答案