【问题标题】:Mongo Index not being used未使用 Mongodb 索引
【发布时间】:2012-02-14 16:31:11
【问题描述】:

我为我正在执行的特定查询围绕多个项目创建了一个索引:

{
    "v" : 1,
    "key" : {
        "MODIFIED" : -1,
        "state" : 1,
        "fail" : 1,
        "generated" : 1
    },
    "ns" : "foo.bar",
    "name" : "MODIFIED_-1_state_1_fail_1_generated"
}

但是,当我执行查询时,它似乎没有使用我的索引。您能否提供一些关于我做错了什么的现场信息?

谢谢!

db.foo.find(    {
    "$or": [
        {
            "MODIFIED": {
                "$gt": {
                    "sec": 1321419600,
                    "usec": 0
                }
            }
        },
        {
            "$or": [
                {"state": "ca"},
                {"state": "ok"}
            ]
        }
    ],
    "$and": [
        {"fail": {"$ne": 1}},
        {"generated": {"$exists": false}}
    ]
}).explain();
{
    "cursor" : "BasicCursor",
    "nscanned" : 464215,
    "nscannedObjects" : 464215,
    "n" : 0,
    "millis" : 7549,
    "nYields" : 0,
    "nChunkSkips" : 0,
    "isMultiKey" : false,
    "indexOnly" : false,
    "indexBounds" : {

    }
}

【问题讨论】:

    标签: mongodb


    【解决方案1】:

    您的索引不能用于您的查询是有充分理由的,我也认为查询本身存在一些问题。它没有达到索引的原因是因为嵌套的 $or 运算符,但我认为您的实际问题是对 MongoDB 中所有可用的运算符缺乏了解:

    首先,您不需要检查状态是“ca”还是“ok”的嵌套 $or 并且(因为这是您没有达到索引的主要原因)可以替换为 state:{$in:["ca", "ok"]}它做同样的事情。现在您的查询是:

    db.foo.find(    {
        "$or": [
            {
                "MODIFIED": {
                    "$gt": {
                        "sec": 1321419600,
                        "usec": 0
                    }
                }
            },
            {
                state:{$in:["ca", "ok"]}            
            }
        ],
        "$and": [
            {"fail": {"$ne": 1}},
            {"generated": {"$exists": false}}
        ]
    }).explain();
    

    它会击中你的索引。您的第二个问题是不需要顶级 $and 子句。请注意AND(OR(A, B), AND(C, D)) = AND(OR(A, B), C, D)。这个查询也是一样的:

    db.foo.find(    {
        "$or": [
            {
                "MODIFIED": {
                    "$gt": {
                        "sec": 1321419600,
                        "usec": 0
                    }
                }
            },
            {
                state:{$in:["ca", "ok"]}            
            }
        ],
    
        "fail": {"$ne": 1},
        "generated": {"$exists": false}
    
    }).explain();
    

    仍然命中索引:

    {
            "clauses" : [
                    {
                            "cursor" : "BtreeCursor MODIFIED_-1_state_1_fail_1_generated_1 multi",
                            "nscanned" : 0,
                            "nscannedObjects" : 0,
                            "n" : 0,
                            "millis" : 1,
                            "nYields" : 0,
                            "nChunkSkips" : 0,
                            "isMultiKey" : false,
                            "indexOnly" : false,
                            "indexBounds" : {
                                    "MODIFIED" : [
                                            [
                                                    {
                                                            "$maxElement" : 1
                                                    },
                                                    {
                                                            "sec" : 1321419600,
                                                            "usec" : 0
                                                    }
                                            ]
                                    ],
                                    "state" : [
                                            [
                                                    {
                                                            "$minElement" : 1
                                                    },
                                                    {
                                                            "$maxElement" : 1
                                                    }
                                            ]
                                    ],
                                    "fail" : [
                                            [
                                                    {
                                                            "$minElement" : 1
                                                    },
                                                    1
                                            ],
                                            [
                                                    1,
                                                    {
                                                            "$maxElement" : 1
                                                    }
                                            ]
                                    ],
                                    "generated" : [
                                            [
                                                    null,
                                                    null
                                            ]
                                    ]
                            }
                    },
                    {
                            "cursor" : "BasicCursor",
                            "nscanned" : 0,
                            "nscannedObjects" : 0,
                            "n" : 0,
                            "millis" : 1,
                            "nYields" : 0,
                            "nChunkSkips" : 0,
                            "isMultiKey" : false,
                            "indexOnly" : false,
                            "indexBounds" : {
    
                            }
                    }
            ],
            "nscanned" : 0,
            "nscannedObjects" : 0,
            "n" : 0,
            "millis" : 1
    }
    

    希望对您有所帮助!顺便说一句,复合索引中的第一个键以 1 开始,第二个键以 -1 开始,这稍微更传统一些。请注意,-1 仅用于确定相对于前一个字段的方向。

    【讨论】:

    • 感谢您的出色回答;再加上一点教育!
    • 已调整,一切正常;快多了。再次感谢您的帮助!
    猜你喜欢
    • 2018-06-22
    • 1970-01-01
    • 1970-01-01
    • 2013-08-25
    • 2022-09-28
    • 2018-02-06
    • 2012-12-09
    • 1970-01-01
    相关资源
    最近更新 更多