Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/solr/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MongoDb提高了聚合框架的性能_Mongodb - Fatal编程技术网

MongoDb提高了聚合框架的性能

MongoDb提高了聚合框架的性能,mongodb,Mongodb,我收集了70亿份数据。 我的数据模型是: {“_id”:ObjectId(“515921e3bbea58d25eb07b22”),“serverId”:0, “计数器ID”:0,“插入”:ISODate(“2013-03-21T00:26:30Z”), “对应值”:0.03256159112788737,“最小值”:-29.96743840887113, “最大值”:20.032561591127887} 我有两个索引serverId,counterId; 我的问题是: {$match:{'in

我收集了70亿份数据。 我的数据模型是:

{“_id”:ObjectId(“515921e3bbea58d25eb07b22”),“serverId”:0, “计数器ID”:0,“插入”:ISODate(“2013-03-21T00:26:30Z”), “对应值”:0.03256159112788737,“最小值”:-29.96743840887113, “最大值”:20.032561591127887}

我有两个索引serverId,counterId; 我的问题是:

{$match:{'inserted':{$gte:新日期(“2013-03-21T00:00:00Z”),$lt: 新日期(“2013-03-22T10:00:00Z”)}},{$group: {{u id:{serverId:'$serverId',counterId:'$counterId'},avgValue:{$avg: “$counterValue”}}

查找平均计数器值,按serverId、counterId分组,并在特定日期之间插入

但它需要13秒我需要它必须需要1秒


我该怎么做呢?

为什么不在插入的列上添加索引呢?它将有一些性能增益。插入当天的索引将帮助您快速获取数据,如此处文档中所指定:。指数将被用来购买美元匹配放在开始。因此,在插入的列上有一个索引

您的索引在以下方面是无用的:

{$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万条记录,你仍然可以从框架中看到糟糕的性能。这是因为,归根结底,没有简单的方法可以做到这一点;这是缓慢的,因为你有多少聚合


更好的替代方法可能是使用预聚合报告,它将通过其他机制(如在客户端中保存)以您需要的形式提供数据,以创建性能查询。

您对插入的字段进行查询,因此插入的字段应具有索引。其他的是无用的(对于这个查询)

如果您想要进行一个完整的索引查询,这将帮助您大大提高性能,那么您还应该将字段放在您查询的索引中。在这种情况下,它还可以使用索引来获取值,而不是去访问每个单独的文档(在磁盘上,可能考虑到文档的数量),这将减慢查询速度

因此,您应该在聚合查询中包含
$project
。索引应为:

{inserted:1, serverId:1, counterId:1, counterValue:1}
和查询:

{
    $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'}}
}

还要注意_id:0。默认情况下,会返回_id字段,该字段不在索引中,因此它将转到每个单独的文档,您不需要的内容。

您的工作集大小与RAM的对比是多少?如果要避免完整的集合扫描,您绝对需要为插入的
列编制索引。