MongoDB - '$group' 性能慢

11

我有一个 MongoDB 集合,其中包含超过 1,000,000 条记录。

每条记录的大小约为 20K(因此总集合大小约为 20GB)。

集合中有一个 'type' 字段(可以有大约10个不同的值)。

我想获取该集合每种类型的计数器。

同时,'type' 字段上有一个索引。

我尝试了两种不同的方法(假设使用 Python 语法):

一种简单粗暴的方法 - 对每个值使用 'count' 调用:

for type_val in my_db.my_colc.distinct('type'):
    counters[type_val] = my_db.my_colc.find({'type' : type_val}).count()

使用聚合框架和'$group'语法:

counters = my_db.my_colc.aggregate([{'$group' :  {'_id': '$type', 'agg_val': { '$sum': 1 } }}])

第一种方法的性能比第二种方法快了约两个数量级。看起来这与count仅运行在索引上而不访问文档有关,而$group必须逐个遍历文档。

是否有一种有效的分组查询方式,可以仅使用索引并使用聚合框架来实现#1中的性能结果?

我正在使用MongoDB 2.6.1

更新: https://jira.mongodb.org/browse/SERVER-11447 在MongoDB Jira上就此问题打开了。


1
首先,聚合框架没有使用索引,请尝试在分组之前添加: {$sort:type}。 - Sammaye
1
添加了,似乎没有帮助。如果$group语句仍然需要逐个访问文档,则排序不会有任何影响... - Baruch Oxman
1
我希望MongoDB在未来的版本中能够添加它。毕竟,这是一个非常简单和常见的用例... - Baruch Oxman
你期望有多少种类型?因为使用distinct with count(distinct()可以使用覆盖查询)可能是可以的。 - Sammaye
1
确实如此,根据该问题,聚合框架已更改为使用不同的方法,该问题基本上跟踪将其放回可以使用覆盖查询的方法,希望很快能完成。 - Sammaye
显示剩余6条评论
1个回答

4

6
如果你需要按照他所说的方式对整个收藏进行分组,那么这并没有太大帮助。 - Sammaye
看起来最高效的方法是使用多查询。如果您不需要实时数据,可以使用缓存层。但是您不能使用聚合框架加速它。 - dantespot

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