0

我的收藏中有 70 亿条数据。我的数据模型是:

{“_id”:ObjectId(“515921e3bbea58d25eb07b22”),“serverId”:0,“counterId”:0,“插入”:ISODate(“2013-03-21T00:26:30Z”),“counterValue”:0.03256159112788737,“最小”:-29.967438408872113,“最大”:20.032561591127887}。

我有 2 个索引 serverId,counterId ;我的查询是:

{$match:{ '插入':{$gte: new Date("2013-03-21T00:00:00Z") , $lt: new Date("2013-03-22T10:00:00Z") } } , {$group : {_id:{serverId:'$serverId', counterId:'$counterId'} ,avgValue:{ $avg : '$counterValue'}}}

查找在特定日期之间插入的按 serverId,counterId 分组的平均 counterValues 。

但这需要 13 秒,我需要它必须需要 1 秒。

我怎样才能做到这一点 ?

4

3 回答 3

1

You query on the inserted field, so the inserted field should have the index. The others are useless (for this query).

If you want to make a full index query which will help you to improve performance a lot, you should also put the fields in the index that you query on. In that case it can also use the index to get the values, instead of heaving to go to each individual document (on disk probably considering that amount of documents), which will slow down the query.

So you should include $project to the aggregation query. Index should be:

{inserted:1, serverId:1, counterId:1, counterValue:1}

And query:

{
    $match:{ 'inserted':{$gte: new Date("2013-03-21T00:00:00Z") , $lt: new Date("2013-03-22T10:00:00Z") } } }, 
    $project: {'serverId':1, 'counterId':1, 'counterValue':1, '_id':0},
    {$group : {_id:{serverId:'$serverId', counterId:'$counterId'} ,avgValue:{ $avg : '$counterValue'}}
}

also notice the _id:0. By default the _id field is returned, which is not in the index so it will go to each individual document, what you don't want.

于 2013-05-12T18:47:23.157 回答
0

为什么不在 Inserted 列上添加索引呢?它会有一些性能提升。插入当天的索引将帮助您快速获取数据,并在此处的文档中指定:http: //docs.mongodb.org/manual/applications/aggregation/。index 将用于购买 $match 放在开头。所以在插入的列上有一个索引

于 2013-04-01T14:20:55.453 回答
0

您的索引对于:

{$match:{ 'inserted':{$gte: new Date("2013-03-21T00:00:00Z") , $lt: new Date("2013-03-22T10:00:00Z") } } }, 
{$group : {_id:{serverId:'$serverId', counterId:'$counterId'} ,avgValue:{ $avg : '$counterValue'}}}

由于$group函数在内存中并且不使用索引,但是,$match可以。如果您像@Devesh 所说的那样放置一个索引,那么inserted您应该在该领域获得更好的性能。

但是,如果这个结果集很大,比如说这 70 亿条记录中的 100 万条记录,您仍然可以从框架中看到糟糕的性能。这是因为,归根结底,没有简单的方法可以做到这一点。它很慢,因为你聚合了多少。

一个更好的选择可能是使用预先聚合的报告,而不是通过其他机制(如在客户端中保存)以您需要的形式提供您的数据,以创建高性能查询。

于 2013-04-02T13:06:11.450 回答