0

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

我的收藏有 7m 文件:

> 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})
4

1 回答 1

4

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

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

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

特别是您希望最小化nscannedObjects(扫描的文档数量)。

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

因此,您的索引还应包括cid

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

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

于 2012-09-12T00:15:12.820 回答