在使用2GB索引的集合上运行$ sum查询会导致20GB的内存使用量

时间:2014-02-04 20:06:22

标签: mongodb indexing aggregation-framework

我有一大堆记录(100M)看起来像:

/* 0 */
{
    "entry_dt" : ISODate("2012-10-19T02:01:35.176Z"),
    "val" : 13.78,
    "order" : {
        "id" : "85PVSQRS4O",
        "orig_dt" : ISODate("2012-10-19T01:25:35.176Z"),
        "discount" : 2.56,
        "year" : 2013,
        "month" : 10,
        "day" : 19,
        "hour" : 25,
        "minute" : 25,
        "dayOfWeek" : 5,
        "week" : 42,
        "quarter" : 3
    }
    "_id" : ObjectId("52e6ed219cea5b5c64c08d8e")
}

我正在对应用程序进行压力测试,以确定每台服务器的最大记录数,内存使用率和速度。我拉出索引统计数据,看到order.year上的索引是2400MB。我在服务器上有大约40GB的内存。所以我运行一个简单的聚合:

db.data.aggregate(
    [
        {"$match":{"$and":[{"order.year":2013}]}},
        {"$limit": 1000},
        {"$project":{"v":"$v", "year": "$order.year"}},
        {"$group":{"_id":"$year","v":{"$sum":"$v"}}},
        {"$sort":{"_id":1}}
    ]
)

(注意:此查询是从查询对象生成的,因此可能需要进行一些调整)

14ms回归。因此,我决定在整个数据集上运行它,而WHAM则非常快地向南移动。如果我只是让它大块消失它将需要大约10分钟。我所看到的是内存从<1GB到20GB(使用的总内存为95%)。

Db stats:

> db.data.stats()
...
{
"indexSizes" : {
...
"order.year_1" : 2516646384,

我写的查询错了吗?为什么在合理大小的索引上运行查询会占用如此多的RAM?

1 个答案:

答案 0 :(得分:0)

我认为查询有点奇怪,你可以尝试将其作为

运行
db.data.aggregate(
    [
        {"$match":{"order.year":2013}},
        {"$limit": 1000},
        {"$group":{"_id":"$order.year","v":{"$sum":"$val"}}},
        {"$project":{"v":"$v", "year": "$_id"}}
    ]
)

我有:

  • 重写match部分
  • 删除了最初的project
  • 在小组后添加项目
  • 已删除sort,因为您要对要求具有特定值的字段进行排序