Mongodb查询(聚合框架)需要非常慢的时间

时间:2015-09-29 12:53:53

标签: mongodb performance aggregation-framework nosql

我的数据集不是很大(> 100000条记录)。 但是我对它们运行的​​聚合查询花了很长时间。

我在_type字段上有一个索引。当我跑步时

db.getCollection('product').find({_type:"healthcare"}).count()

我在0.015秒内得到答复......

但是当我跑来跑去时

db.getCollection('product').aggregate([{$group:{_id:"$_type",sum:{$sum:1}}}])

我等待40秒才能得到答复。

像这样的仅索引聚合查询可能出现什么问题?我应该在哪里找到问题?

MongoDB版本是3.0+。 wiredTiger数据存储。以下是db.stats()输出:

{
    "collections" : 3,
    "objects" : 113090,
    "avgObjSize" : 259186.2551949774497189,
    "dataSize" : 29311373600.0000000000000000,
    "storageSize" : 29317480288.0000000000000000,
    "numExtents" : 36,
    "indexes" : 4,
    "indexSize" : 15379056.0000000000000000,
    "fileSize" : 32130465792.0000000000000000,
    "nsSizeMB" : 16,
    "extentFreeList" : {
        "num" : 2,
        "totalSize" : 9.85907e+06
    },
    "dataFileVersion" : {
        "major" : 4,
        "minor" : 22
    },
    "ok" : 1.0000000000000000
}

1 个答案:

答案 0 :(得分:1)

根据pipeline operators and indexes上的文档,$group管道运营商无法使用索引:

  

$match$sort管道运营商可以利用索引   当它们出现在管道的开头时。

     

2.4版中的新功能: $geoNear管道运算符利用了地理空间索引。使用$geoNear时,$geoNear管道   操作必须作为聚合管道中的第一个阶段出现。

     

即使管道使用索引,聚合仍然需要   获取实际文件;即索引不能完全覆盖   聚合管道。

     

在2.6版中更改:在以前的版本中,对于非常精选的用例,索引可以覆盖管道。

因此,您的$group聚合很慢,因为它会使用完整的收集扫描。

但是,值得注意的是,与您所比较的aggregate查询的find相当于:

db.getCollection('product').aggregate([
    {$match: {_type: 'healthcare'}},
    {$group: {_id: null, sum: {$sum: 1}}}
])

因为该查询以$match运算符开头,所以它会使用索引,性能应该更具可比性。