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



我有一组大型记录(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的MEM。所以我运行一个简单的聚合:

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

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

以14毫秒返回。因此,我决定在整个数据集上运行它,然后它的速度非常快。如果我只是放开它,大约需要10分钟。我看到的是,内存从< 1GB到20GB(将总MEM用于95%)。

db统计:

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

我写了错误的查询吗?为什么在合理尺寸的索引上运行查询会占用这么多RAM?

我认为查询有点奇怪,您能尝试以

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

我有:

  • 重写match Part
  • 删除了初始project
  • 添加了小组之后的项目
  • 删除了sort,因为您在需要某个值的字段上进行排序

最新更新