当value为null时,Mongodb不使用索引

时间:2016-06-20 09:32:54

标签: mongodb optimization indexing

我为三个属性创建了索引 - a:1,b:1,c:-1

搜索时:

{a: false, b: null, c: {"$lt" : ISODate("2016-06-19T12:19:37.177Z")}}

Mongo使用创建的索引,但仍然需要获取" b"。因此索引仅用于。

但是当我搜索:

{a: false, b: "some value", c: {"$lt" : ISODate("2016-06-19T12:19:37.177Z")}}

我确实使用整个索引。

所以问题是为什么当value为null时,Mongo不使用整个索引?

稀疏选项不会改变任何内容。

{
"queryPlanner" : {
    "plannerVersion" : 1,
    "namespace" : "db.collection",
    "indexFilterSet" : false,
    "parsedQuery" : {
        "$and" : [ 
            {
                "a" : {
                    "$eq" : false
                }
            }, 
            {
                "b" : {
                    "$eq" : null
                }
            }, 
            {
                "c" : {
                    "$lt" : ISODate("2016-06-19T12:19:37.177Z")
                }
            }
        ]
    },
    "winningPlan" : {
        "stage" : "COUNT",
        "inputStage" : {
            "stage" : "KEEP_MUTATIONS",
            "inputStage" : {
                "stage" : "FETCH",
                "filter" : {
                    "b" : {
                        "$eq" : null
                    }
                },
                "inputStage" : {
                    "stage" : "IXSCAN",
                    "keyPattern" : {
                        "a" : NumberLong(1),
                        "b" : NumberLong(1),
                        "c" : NumberLong(-1)
                    },
                    "indexName" : "a_1_b_1_c_-1",
                    "isMultiKey" : false,
                    "direction" : "forward",
                    "indexBounds" : {
                        "a" : [ 
                            "[false, false]"
                        ],
                        "b" : [ 
                            "[MinKey, MaxKey]"
                        ],
                        "c" : [ 
                            "(new Date(1466338777177), true)"
                        ]
                    }
                }
            }
        }
    },
    "rejectedPlans" : []
},
"executionStats" : {
    "executionSuccess" : true,
    "nReturned" : 0,
    "executionTimeMillis" : 3,
    "totalKeysExamined" : 578,
    "totalDocsExamined" : 578,
    "executionStages" : {
        "stage" : "COUNT",
        "nReturned" : 0,
        "executionTimeMillisEstimate" : 0,
        "works" : 579,
        "advanced" : 0,
        "needTime" : 578,
        "needFetch" : 0,
        "saveState" : 4,
        "restoreState" : 4,
        "isEOF" : 1,
        "invalidates" : 0,
        "nCounted" : 577,
        "nSkipped" : 0,
        "inputStage" : {
            "stage" : "KEEP_MUTATIONS",
            "nReturned" : 577,
            "executionTimeMillisEstimate" : 0,
            "works" : 579,
            "advanced" : 577,
            "needTime" : 1,
            "needFetch" : 0,
            "saveState" : 4,
            "restoreState" : 4,
            "isEOF" : 1,
            "invalidates" : 0,
            "inputStage" : {
                "stage" : "FETCH",
                "filter" : {
                    "b" : {
                        "$eq" : null
                    }
                },
                "nReturned" : 577,
                "executionTimeMillisEstimate" : 0,
                "works" : 579,
                "advanced" : 577,
                "needTime" : 1,
                "needFetch" : 0,
                "saveState" : 4,
                "restoreState" : 4,
                "isEOF" : 1,
                "invalidates" : 0,
                "docsExamined" : 578,
                "alreadyHasObj" : 0,
                "inputStage" : {
                    "stage" : "IXSCAN",
                    "nReturned" : 578,
                    "executionTimeMillisEstimate" : 0,
                    "works" : 579,
                    "advanced" : 578,
                    "needTime" : 0,
                    "needFetch" : 0,
                    "saveState" : 4,
                    "restoreState" : 4,
                    "isEOF" : 1,
                    "invalidates" : 0,
                    "keyPattern" : {
                        "a" : NumberLong(1),
                        "b" : NumberLong(1),
                        "c" : NumberLong(-1)
                    },
                    "indexName" : "a_1_b_1_c_-1",
                    "isMultiKey" : false,
                    "direction" : "forward",
                    "indexBounds" : {
                        "c" : [ 
                            "[false, false]"
                        ],
                        "b" : [ 
                            "[MinKey, MaxKey]"
                        ],
                        "c" : [ 
                            "(new Date(1466338777177), true)"
                        ]
                    },
                    "keysExamined" : 578,
                    "dupsTested" : 0,
                    "dupsDropped" : 0,
                    "seenInvalidated" : 0,
                    "matchTested" : 0
                }
            }
        }
    }
},
"serverInfo" : {
    "host" : "vagrant-ubuntu-trusty-64",
    "port" : 27017,
    "version" : "3.0.10",
    "gitVersion" : "1e0512f8453d103987f5fbfb87b71e9a131c2a60"
},
"ok" : 1.0

}

1 个答案:

答案 0 :(得分:0)

经过一些研究,我了解到索引和搜索null的工作方式与其他值完全相同。

无论如何,在做解释时你会发现,对于“null”,你有一个额外的阶段称为“FETCH”,这可能会令人困惑。尽管检查的文档/密钥数量完全相同(测试数据库包含对称数据)。