MongoDB复合索引性能

时间:2016-03-23 10:23:50

标签: mongodb indexing

我在理解复合索引的基本概念时遇到了麻烦。 假设我有一个这个模式的集合:

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

https://docs.mongodb.org/manual/core/index-compound/中,它非常清楚地表明,我明白,这个索引:{ field1: 1, field: 2}仅支持field1field1 AND field2上的查询,这是有道理的。

现在,如果我想支持始终使用字段1的所有字段(1,2和3)的查询,该怎么办? 我想支持在所有field1 AND field2上查询field1 AND field3field1 AND field2 AND field3的选项。

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

例如,如果我有一个索引:{field1: 1, field2: 1, field3: 1}并且我查询field1 AND field3,它将使用此索引,但field2上的索引边界将是"[MinKey, MaxKey]" }。 是否值得创建另一个索引:{field1: 1, field3: 1}

1 个答案:

答案 0 :(得分:0)

如果您尝试使用这些文档和索引创建集合,然后对查询进行说明,mongo将选择索引:{field1: 1, field3: 1}并拒绝其他计划。这表明mongo找到一个比另一个索引更好的索引。

例如,解释返回以下内容:

"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。如果它们没有那么它将把索引保存在磁盘上,这显然要慢一些。那么最好的折衷方案可能是在所有三个字段上使用索引,因为这比没有索引好,并且涉及的维护少于三个索引