我正在运行Mongo DB 2.4.6版本的标准Homebrew安装,我有一个名为'items'的数据库,里面有600k文件。
我写了以下查询来查找项目集合的前五大品牌:
db.items.aggregate([
{ $group: { _id: '$brand', size: { $sum: 1}}},
{ $sort: {"size": -1}},
{ $limit: 5}
])
返回我预期的结果,但坦率地说,完成的时间比我想象的要长得多。这是个人资料数据:
{
"op" : "command",
"ns" : "insights-development.$cmd",
"command" : {
"aggregate" : "items",
"pipeline" : [
{
"$group" : {
"_id" : "$brand",
"size" : {
"$sum" : 1
}
}
},
{
"$sort" : {
"size" : -1
}
},
{
"$limit" : 5
}
]
},
"ntoreturn" : 1,
"keyUpdates" : 0,
"numYield" : 3,
"lockStats" : {
"timeLockedMicros" : {
"r" : NumberLong(3581974),
"w" : NumberLong(0)
},
"timeAcquiringMicros" : {
"r" : NumberLong(1314151),
"w" : NumberLong(10)
}
},
"responseLength" : 267,
"millis" : 2275,
"ts" : ISODate("2013-11-23T18:16:33.886Z"),
"client" : "127.0.0.1",
"allUsers" : [ ],
"user" : ""
}
以下是db.items.stats()
的ouptut:
{
"sharded" : false,
"primary" : "a59aff30810b066bbe31d1fae79596af",
"ns" : "insights-development.items",
"count" : 640590,
"size" : 454491840,
"avgObjSize" : 709.4894394230319,
"storageSize" : 576061440,
"numExtents" : 14,
"nindexes" : 10,
"lastExtentSize" : 156225536,
"paddingFactor" : 1,
"systemFlags" : 1,
"userFlags" : 0,
"totalIndexSize" : 165923744,
"indexSizes" : {
"_id_" : 17889088,
"demographic_1" : 14741328,
"brand_1" : 17946320,
"retailer_1" : 18690336,
"color_1" : 15738800,
"style_1" : 18951968,
"classification_1" : 15019312,
"placement_1" : 19107312,
"state_1" : 12394816,
"gender_1" : 15444464
},
"ok" : 1
}
我对MongoDB相当新,所以我希望有人能指出为什么这个聚合需要这么长时间才能运行,如果有什么我可以做的加速,因为在我看来,600k不是大量的文件更多Mongo运行计算。
答案 0 :(得分:2)
如果您有“品牌”字段的索引,那么在管道的开头添加{$sort:{brand:1}}
可能有助于提高性能。您现在没有看到良好表现的原因可能是由于需要按品牌扫描每个文档。如果有索引,那么它可以仅用于扫描索引而不是所有文档。并且排序(使用索引)可以加速分组,在某些情况下,按字段排序的结果是有益的。
如果您在brand
上创建了索引但没有看到任何改进,请尝试在删除索引之前添加$sort
。如果您已经有一个索引brand
是第一个字段,那么您就不需要在brand
上添加另一个索引 - 将自动使用复合索引。