提问者:小点点

MongoDB复合指数性能


我很难理解复合索引的基本概念。假设我有一个具有以下模式的集合:

{
    _id: 1,
    field1: 'aaa',
    field2: 'bbb',
    field3: 'ccc'
}

在https://docs.mongodb.org/manual/core/index-compound/中,它非常清楚地指出,而且我理解,这个索引:将只支持对的查询,而且对都支持,这是有意义的。

现在,如果我想支持对始终使用字段1的所有字段(1,2和3)的查询,该怎么办?我希望支持在以及在所有上查询的选项。

我知道可以为这些查询选项中的每一个创建复合索引,但问题是我是否可以使用更少的复合来以相同的性能进行查询。

例如,如果我有一个索引:,并且我查询,它将使用这个索引,但是上的索引界限将是。是否值得创建另一个索引:


共1个答案

匿名用户

如果您尝试使用这些文档和索引创建一个集合,然后对查询执行解释,mongo将选择索引:并拒绝其他计划。这表明mongo发现一个索引比另一个索引更可取。

例如,explain返回以下内容:

"winningPlan" : {
    "stage" : "FETCH",
    "inputStage" : {
        "stage" : "IXSCAN",
        "keyPattern" : {
            "field1" : 1,
            "field3" : 1
        },
        "indexName" : "field1_1_field3_1",
        "isMultiKey" : false,
        "isUnique" : false,
        "isSparse" : false,
        "isPartial" : false,
        "indexVersion" : 1,
        "direction" : "forward",
        "indexBounds" : {
            "field1" : [
                "[\"aaa\", \"aaa\"]"
            ],
            "field3" : [
                "[\"ccc\", \"ccc\"]"
            ]
        }
    }
},
"rejectedPlans" : [
    {
        "stage" : "FETCH",
        "filter" : {
            "field3" : {
                "$eq" : "ccc"
            }
        },
        "inputStage" : {
            "stage" : "IXSCAN",
            "keyPattern" : {
                "field1" : 1,
                "field2" : 1
            },
            "indexName" : "field1_1_field2_1",
            "isMultiKey" : false,
            "isUnique" : false,
            "isSparse" : false,
            "isPartial" : false,
            "indexVersion" : 1,
            "direction" : "forward",
            "indexBounds" : {
                "field1" : [
                    "[\"aaa\", \"aaa\"]"
                ],
                "field2" : [
                    "[MinKey, MaxKey]"
                ]
            }
        }
    },
    {
        "stage" : "FETCH",
        "inputStage" : {
            "stage" : "IXSCAN",
            "keyPattern" : {
                "field1" : 1,
                "field2" : 1,
                "field3" : 1
            },
            "indexName" : "field1_1_field2_1_field3_1",
            "isMultiKey" : false,
            "isUnique" : false,
            "isSparse" : false,
            "isPartial" : false,
            "indexVersion" : 1,
            "direction" : "forward",
            "indexBounds" : {
                "field1" : [
                    "[\"aaa\", \"aaa\"]"
                ],
                "field2" : [
                    "[MinKey, MaxKey]"
                ],
                "field3" : [
                    "[\"ccc\", \"ccc\"]"
                ]
            }
        }
    }
]

然而,还有索引大小的问题,以及您要创建的所有索引是否都能与数据库工作集一起放入RAM中。如果它们没有,那么它将把索引保存在磁盘上,而磁盘读取速度要慢得多。最好的折衷办法可能是在所有三个字段上使用索引,因为这比没有索引要好,并且比三个索引所涉及的维护要少