MongoDB聚合框架的索引优化

22

我在Mongo 2.4.4中有一个match-unwind-group-sort聚合管道,需要加快聚合速度。

匹配操作涉及对16个字段的范围查询。我已经使用.explain()方法优化了范围查询 (即创建复合索引)。是否有类似于优化聚合的功能?我正在寻找像这样的东西:

db.col.aggregate([]).explain()

另外,我是否应该专注于索引优化?


1
最新的不稳定版本中存在这个问题:https://jira.mongodb.org/browse/SERVER-4504,但在那之前没有,也没有索引被用于匹配之后的操作,因此索引优化不是一个好的选择。 - Sammaye
@Sammaye 这是错误的,match 当然使用索引,sort 也是。 - Asya Kamsky
@AsyaKamsky 我刚才就是这么说的,我实际上是指在匹配之后,也就是在 $group 中。 - Sammaye
索引优化是提高性能的唯一途径。 - Asya Kamsky
@AsyaKamsky 如果你已经像他在问题中所说的那样进行了优化,那就不用了。 - Sammaye
1个回答

21

关于第一个问题,是的,你可以解释聚合。

db.collection.runCommand("aggregate", {pipeline: YOUR_PIPELINE, explain: true})

对于第二个问题,你创建的用于优化范围查询的索引也会应用于聚合管道的$match阶段,如果它们出现在管道的开头。因此,你确实需要专注于索引优化。

请参见Pipeline Operators and Indexes

更新2

更多关于aggregateexplain的信息:在版本2.4上不可靠;在2.6+上它不提供查询执行数据。https://groups.google.com/forum/#!topic/mongodb-user/2LzAkyaNqe0

更新1

MongoDB 2.4.5上聚合解释的记录。

$ mongo so
MongoDB shell version: 2.4.5
connecting to: so
> db.q19329239.runCommand("aggregate", {pipeline: [{$group: {_id: '$user.id', hits: {$sum: 1}}}, {$match: {hits: {$gt: 10}}}], explain: true})
{
    "serverPipeline" : [
        {
            "query" : {

            },
            "projection" : {
                "user.id" : 1,
                "_id" : 0
            },
            "cursor" : {
                "cursor" : "BasicCursor",
                "isMultiKey" : false,
                "n" : 1031,
                "nscannedObjects" : 1031,
                "nscanned" : 1031,
                "nscannedObjectsAllPlans" : 1031,
                "nscannedAllPlans" : 1031,
                "scanAndOrder" : false,
                "indexOnly" : false,
                "nYields" : 0,
                "nChunkSkips" : 0,
                "millis" : 0,
                "indexBounds" : {

                },
                "allPlans" : [
                    {
                        "cursor" : "BasicCursor",
                        "n" : 1031,
                        "nscannedObjects" : 1031,
                        "nscanned" : 1031,
                        "indexBounds" : {

                        }
                    }
                ],
                "server" : "ficrm-rafa.local:27017"
            }
        },
        {
            "$group" : {
                "_id" : "$user.id",
                "hits" : {
                    "$sum" : {
                        "$const" : 1
                    }
                }
            }
        },
        {
            "$match" : {
                "hits" : {
                    "$gt" : 10
                }
            }
        }
    ],
    "ok" : 1
}

服务器版本。

$ mongo so
MongoDB shell version: 2.4.5
connecting to: so
> db.version()
2.4.5

你只能解释在不稳定的情况下进行的聚合查询,因此不应认为你可以这样做,你必须让人们意识到这不是生产就绪的版本,而且版本不稳定且可能会更改。 - Sammaye
不,你可以解释MongoDB 2.4中的聚合操作。我经常这样做。 - Rafa Viotti
由于索引仅用于$match、$skip、$sort和$limit,如果它们在展开和分组之前出现,我不确定您的陈述是否正确,即他专注于已经优化的索引。 - Sammaye
2
啊,我知道为什么了,这个在分片的情况下不起作用,所以这个功能一直被标记为不完整,除非你更深入地阅读相关任务,否则看不出来。 - Sammaye
2
@TomSwifty 这可能意味着您需要查看您的工作流程,MapReduce 是一项非常缓慢的任务,旨在长时间进行实质性聚合。 - Sammaye
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接