【问题标题】:mongo aggregation speedmongo聚合速度
【发布时间】:2012-09-11 23:49:06
【问题描述】:

我是 mongo 的新用户(对 mysql 有丰富的经验),它似乎有一些有趣的优点和缺点。显然,优点是您可以保存的数据大小和写入记录的速度。我有一个应用程序,我正在将许多日志写入一个集合,到目前为止我有大约 7m。我的问题是一个看似简单的查询需要很长的时间。让我解释一下。

我的收藏有 700 万份文档:

> db.alpha2.count()
7257619

现在我想计算给定 cid 的所有记录并且时间戳小于某个数字(此示例具有未来的时间戳,因此它应该计算所有内容):

> db.alpha2.find({'ts': {'$lt': 1446457607}, 'cid': '2636518'}).count()
7257619

这是问题查询,需要整整 58 秒 才能将这个号码返回给我!从概念上讲,这是一个非常简单的查询,在某种程度上相当于 sql 世界中的这个:

select count(*) from alpha2 where cid=2636518 and ts<1446457607

我没有等效的表,但根据我的经验,我认为在 mysql 中运行不到 0.1 秒。那我该怎么办?我计划对比 7m 记录大得多的数据集进行大量聚合。我也在做一些稍微困难的事情(减少地图),而且情况要糟糕得多(几分钟)。我需要这个时间少于一秒。我究竟做错了什么?这个时间成本是 mongo 预期的吗?

在我对上述查询进行计时之前,我在 ts 值上放置了一个索引:

db.alpha2.ensureIndex({ts:1})

【问题讨论】:

  • 如果 ts

标签: mongodb


【解决方案1】:

为了确定count(),MongoDB 必须找到所有匹配的文档。

您可以explain()查询查看索引是如何使用的:

 db.alpha2.find({'ts': {'$lt': 1446457607}, 'cid': '2636518'}).explain()

您尤其希望最小化nscannedObjects(扫描的文档数)。

您最好的标准情况是对计数中涉及的所有字段进行索引(并确保索引适合可用 RAM)。

因此,您的索引也应该包含cid

 db.alpha2.ensureIndex({ts:1, cid:1})

如果您经常进行计数,则最好通过incremental map/reduce 之类的过程来存储和更新这些数据(如果这适用于您的用例)。

【讨论】:

  • 在 MongoDB 的问题跟踪器中还有一些开放的建议,用于提高各种用例的计数性能(集合中的所有文档、每个属性、查找不同的值……)。例如:SERVER-1752(提高count({attr:val})的性能)。
  • 请注意,SERVER-1752 已在 2.3.2 开发版本中得到解决,因此对于一些常见用例,在 MongoDB 2.4 生产版本中计数的性能将得到显着提升。
猜你喜欢
  • 1970-01-01
  • 2015-04-06
  • 2021-12-21
  • 2018-07-15
  • 2017-08-24
  • 2018-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多