【问题标题】:MongoDB optimize indexes for aggregationMongoDB 优化聚合索引
【发布时间】:2016-08-10 18:23:52
【问题描述】:

我收集了一个包含大约 160 万个寄存器的集合。该咨询是其他更复杂的简单示例,但说明我认为使用的索引优化不佳。

db.getCollection('cbAlters').runCommand("aggregate", {pipeline: [
{
    $match: { cre_carteraId: "31" }
},
{
    $group: { _id: { ca_tramomora: "$cre_tramoMora" },
            count: { $sum: 1 } }
}
]})

该查询大约需要 5 秒。该colleccion 有25 个索引配置为不同的咨询。根据查询说明使用的是:

{
        "v" : 1,
        "key" : {
            "cre_carteraId" : 1,
            "cre_periodo" : 1,
            "cre_tramoMora" : 1,
            "cre_inactivo" : 1
        },
        "name" : "cartPerTramInact",
        "ns" : "basedatos.cbAlters"
    },

我创建了一个适应这个特定查询的索引:

{
    "v" : 1,
    "key" : {
        "cre_carteraId" : 1,
        "cre_tramoMora" : 1
    },
    "name" : "cartPerTramTest",
    "ns" : "basedatos.cbAlters"
}

查询优化器拒绝此索引,并建议我使用初始索引。我的查询解释的输出如下所示:

{
    "waitedMS" : NumberLong(0),
    "stages" : [ 
        {
            "$cursor" : {
                "query" : {
                    "cre_carteraId" : "31"
                },
                "fields" : {
                    "cre_tramoMora" : 1,
                    "_id" : 0
                },
                "queryPlanner" : {
                    "plannerVersion" : 1,
                    "namespace" : "basedatos.cbAlters",
                    "indexFilterSet" : false,
                    "parsedQuery" : {
                        "cre_carteraId" : {
                            "$eq" : "31"
                        }
                    },
                    "winningPlan" : {
                        "stage" : "PROJECTION",
                        "transformBy" : {
                            "cre_tramoMora" : 1,
                            "_id" : 0
                        },
                        "inputStage" : {
                            "stage" : "IXSCAN",
                            "keyPattern" : {
                                "cre_carteraId" : 1,
                                "cre_periodo" : 1,
                                "cre_tramoMora" : 1,
                                "cre_inactivo" : 1
                            },
                            "indexName" : "cartPerTramInact",
                            "isMultiKey" : false,
                            "isUnique" : false,
                            "isSparse" : false,
                            "isPartial" : false,
                            "indexVersion" : 1,
                            "direction" : "forward",
                            "indexBounds" : {
                                "cre_carteraId" : [ 
                                    "[\"31\", \"31\"]"
                                ],
                                "cre_periodo" : [ 
                                    "[MinKey, MaxKey]"
                                ],
                                "cre_tramoMora" : [ 
                                    "[MinKey, MaxKey]"
                                ],
                                "cre_inactivo" : [ 
                                    "[MinKey, MaxKey]"
                                ]
                            }
                        }
                    },
                    "rejectedPlans" : [ 
                        {
                            "stage" : "PROJECTION",
                            "transformBy" : {
                                "cre_tramoMora" : 1,
                                "_id" : 0
                            },
                            "inputStage" : {
                                "stage" : "IXSCAN",
                                "keyPattern" : {
                                    "cre_carteraId" : 1,
                                    "cre_tramoMora" : 1
                                },
                                "indexName" : "cartPerTramTest",
                                "isMultiKey" : false,
                                "isUnique" : false,
                                "isSparse" : false,
                                "isPartial" : false,
                                "indexVersion" : 1,
                                "direction" : "forward",
                                "indexBounds" : {
                                    "cre_carteraId" : [ 
                                        "[\"31\", \"31\"]"
                                    ],
                                    "cre_tramoMora" : [ 
                                        "[MinKey, MaxKey]"
                                    ]
                                }
                            }
                        }
                    ]
                }
            }
        }, 
        {
            "$group" : {
                "_id" : {
                    "ca_tramomora" : "$cre_tramoMora"
                },
                "count" : {
                    "$sum" : {
                        "$const" : 1.0
                    }
                }
            }
        }
    ],
    "ok" : 1.0
}

那么,为什么优化器更喜欢调整较少的索引呢?该聚合的 indexFilterSet(针对索引过滤的结果)是否应该为真?

我该如何改进这个索引,或者查询出了什么问题?

我对 mongoDB 没有太多经验,感谢任何帮助

【问题讨论】:

  • 一般来说,过多的索引会破坏派对。尽量只保留相关的。这就像您的播放列表中的所有其他歌曲一样。
  • 只有开头的$match可以使用索引,见stackoverflow.com/questions/20170636/…

标签: mongodb mongodb-query aggregation-framework mongodb-indexes


【解决方案1】:

只要您有索引 cartPerTramInact,优化器就不会使用您的 cartPerTramTest 索引,因为第一个字段相同且顺序相同。

这也适用于其他索引。当索引具有相同顺序的相同键(如 a.b.c.d、a.b.d、a.b)并且您查询使用字段 a.b 时,它将支持 a.b.c.d。无论如何,您不需要该索引 a.b,因为您已经有两个涵盖 a.b 的索引(a.b.c.d 和 a.b.d) 索引 a.b.d 仅在您使用这些字段 a.b.d 进行查询时使用,但如果 a.b 已经非常有选择性,则使用索引 a.b.c.d 仅使用部分 a.b 进行选择并进行“全表扫描”以找到该 d 可能会更快

【讨论】:

    猜你喜欢
    • 2013-11-04
    • 2018-02-18
    • 1970-01-01
    • 2021-09-03
    • 1970-01-01
    • 1970-01-01
    • 2015-10-05
    • 2020-07-09
    • 2019-07-22
    相关资源
    最近更新 更多