【发布时间】:2020-04-22 16:11:32
【问题描述】:
根据Mongo最新的$group documentation,对$first有一个特别的优化:
优化返回每个组的第一个文档
如果管道按相同字段排序和分组,并且 $group 阶段仅使用 $first 累加器运算符,请考虑在与排序顺序匹配的分组字段上添加索引。在某些情况下,$group 阶段可以使用索引快速找到每个组的第一个文档。
这是有道理的,因为 $group 阶段中的每个 bin 只需要有序索引中的第一个条目。不幸的是,在我的测试中,我得到了一个查询,它在大约 1 秒内呈现约 800k 排序记录,然后将它们传递给 $group,其中大约需要 10 秒来呈现 key 的某些值的 1.7k 输出文档(参见下面的例子)。对于key 的其他值,超时时间为 300 秒。无论key 是什么,组中都应该正好有 1704 个 bin,并且这些查询 bin 应该被索引中的前三个条目覆盖,据我所知。我错过了什么吗?
db.getCollection('time_series').aggregate([
{
'$match': {
'organization_id': 1,
'key': 'waffle_count'
}
},
{
'$sort': {
'key': 1, 'asset_id': 1, 'date_time': - 1
}
},
{
'$group': {
'_id': {
'key': '$key', 'asset_id': '$asset_id'
},
'value': {
'$first': '$value'
}
}
}
]);
这是索引:
{
"organization_id": 1,
"key": 1,
"asset_id": 1,
"date_time": -1
}
【问题讨论】:
-
.explain说什么?这也取决于你是否有复合索引或单字段索引 -
很难用可用信息分析您的查询。由于复合索引和索引前缀的性质,“优化以返回每个组的第一个文档”的示例可能不适用于您的情况。因此,即使是文档也表明,“可能是”(我自己的话)。但是,您可以单独尝试以下复合索引,并查看查询以及查询计划的结果是什么:@ 987654328@ 和
{ "key": 1, "asset_id": 1, "date_time": -1, "value": 1, "organization_id": 1 }. -
@Ashh,.explain 是我如何知道通过排序的所有内容都在大约 1 秒内运行,从索引返回约 800k 排序条目,并且查询的其余部分在最佳情况下需要 10 秒。
标签: mongodb mongodb-query aggregation-framework query-optimization mongodb-indexes