MongoDB复合索引性能

MongoDB复合索引性能,mongodb,indexing,Mongodb,Indexing,我很难理解复合索引的基本概念。 假设我有一个具有此模式的集合: { _id: 1, field1: 'aaa', field2: 'bbb', field3: 'ccc' } 在这篇文章中,我明白,这个索引:{field1:1,field:2}将只支持对field1以及对field1和field2的查询,这是有意义的 现在,如果我想支持对所有字段(1、2和3)的查询,其中字段1总是被使用,该怎么办? 我想支持在所有field1和field2和field3上查询f

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

{
    _id: 1,
    field1: 'aaa',
    field2: 'bbb',
    field3: 'ccc'
}
在这篇文章中,我明白,这个索引:
{field1:1,field:2}
将只支持对
field1
以及对
field1和field2
的查询,这是有意义的

现在,如果我想支持对所有字段(1、2和3)的查询,其中字段1总是被使用,该怎么办? 我想支持在所有
field1和field2和field3上查询
field1和field2
field1和field3
的选项

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

例如,如果我有一个索引:
{field1:1,field2:1,field3:1}
,我查询
field1和field3
,它将使用这个索引,但是
field2
上的索引边界将是
“[MinKey,MaxKey]”

是否值得创建另一个索引:
{field1:1,field3:1}

如果尝试使用这些文档和索引创建集合,然后对查询进行解释,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。如果他们不这样做,那么它将把索引保存在磁盘上,这会大大降低读取速度。最好的折衷办法可能是在所有三个字段上使用索引,因为这比没有索引好,并且比三个索引需要更少的维护

也许您可以使用、使用和不使用索引测试数据
{field1:1,field3:1},比较这两个结果,它会给你一些线索…@zangw我这么做了,这就是为什么我知道它使用带有
[MinKey,MaxKey]
索引边界的索引。但它并没有给我性能评估离开等式的RAM,我感兴趣的是知道这两种性能之间的区别。我知道这个指数比其他指数更受欢迎,但它值得吗?