【问题标题】:Mongodb does not use index when value is null值为空时MongoDB不使用索引
【发布时间】:2016-10-21 12:05:53
【问题描述】:

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

搜索时:

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

Mongo 使用创建的索引,但仍需要获取“b”。所以index只用于a。

但是当我搜索时:

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

我确实使用了整个索引。

那么问题是为什么 Mongo 在 value 为 null 时不使用整个索引?

稀疏选项不会改变任何东西。

{
"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

}

【问题讨论】:

    标签: mongodb optimization indexing


    【解决方案1】:

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

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

    【讨论】:

      猜你喜欢
      • 2012-01-16
      • 2020-02-18
      • 1970-01-01
      • 2021-09-21
      • 1970-01-01
      • 2018-02-06
      • 1970-01-01
      • 2021-04-17
      • 2015-08-18
      相关资源
      最近更新 更多