我的数据集不是很大(> 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
}
答案 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
运算符开头,所以它会使用索引,性能应该更具可比性。