mongodb - Mongodb - executionStats executionTimeMillis 方式比每个阶段的 executionTimeMillisEstimate 的累积时间长
问题描述
我有一个具有多个阶段的 mongo 聚合,并且该$match
阶段的一部分是geoWithin
跨大量点的操作。
我正在使用带有 executionStats 的解释来分析聚合,并注意到获胜计划的执行统计数据在每个阶段都非常低executionTimeMillisEstimate
,但总体而言executionTimeMillis
是巨大的。我说的是~150倍的差异。
我注意到 queryPlanner 有一个被拒绝的计划,其中使用所有次要索引进行查询,而不仅仅是 geoWithin 的位置索引,这是获胜计划中使用的。但是由于获胜的计划被缓存了,我认为这并不重要。
但是,黑白时间的差异又太大了,不能仅仅因为被拒绝的计划构建,还有什么原因呢?
执行计划:
{
"executionSuccess": true,
"nReturned": 101,
"executionTimeMillis": 85264,
"totalKeysExamined": 196,
"totalDocsExamined": 315,
"executionStages": {
"stage": "FETCH",
"filter": {
"$and": [{
"something": {
"$eq": "a"
}
},
{
"other": {
"$eq": "abc"
}
}
]
},
"nReturned": 101,
"executionTimeMillisEstimate": 312,
"works": 196,
"advanced": 101,
"needTime": 95,
"needYield": 0,
"saveState": 88,
"restoreState": 88,
"isEOF": 0,
"docsExamined": 150,
"alreadyHasObj": 150,
"inputStage": {
"stage": "FETCH",
"filter": {
"$or": [{
"location": {
"$geoWithin": {
"$centerSphere": [
[
0,
1
],
0.0000783927971443699
]
}
}
},
{},
{}
]
},
"nReturned": 150,
"executionTimeMillisEstimate": 312,
"works": 196,
"advanced": 150,
"needTime": 46,
"needYield": 0,
"saveState": 88,
"restoreState": 88,
"isEOF": 0,
"docsExamined": 165,
"alreadyHasObj": 0,
"inputStage": {
"stage": "IXSCAN",
"nReturned": 165,
"executionTimeMillisEstimate": 0,
"works": 196,
"advanced": 165,
"needTime": 31,
"needYield": 0,
"saveState": 88,
"restoreState": 88,
"isEOF": 0,
"keyPattern": {
"location": "2dsphere"
},
"indexName": "location",
"isMultiKey": false,
"multiKeyPaths": {
"location": []
},
"isUnique": false,
"isSparse": false,
"isPartial": false,
"indexVersion": 2,
"direction": "forward",
"indexBounds": {
"location": [
"[0, 1]",
""
]
},
"keysExamined": 196,
"seeks": 32,
"dupsTested": 0,
"dupsDropped": 0
}
}
}
}
解决方案
总数executionTimeMillis
包括一些未在个人计划中考虑的事项,例如:
- 计划所用时间
查询计划器评估所有候选索引并计划确定要测试的索引。这可能需要每个候选计划的非零时间,并增加总执行时间。 - 锁定获取
计划时只检查索引/文档的一小部分。一旦选择了计划,它就会运行到完成以获取执行统计信息。如果发生其他操作导致查询执行器等待锁,这将增加总时间超过估计 - 磁盘延迟
与锁类似,如果在计划阶段从磁盘读取文档非常快,但在执行过程中会慢很多,则总时间将大于估计
可能还有其他考虑因素,如果我想到任何我会在这里添加它们。如果其他人记得我忘记的一个,请随时提出修改建议!
推荐阅读
- reactjs - 将脚本标签和函数添加到下一个 js?
- python - 如何在 Flask 上获取完整的文件路径?
- firebase - 如何链接firebase中不同集合中的两个文档以将它们一起更新?
- ios - 天气图标未显示在天气 pp 的图像视图中
- python - 如何在 Google Cloud Platform(计算引擎)中使用 PyCharm 或 Anaconda Spyder?
- sql - SQL通过从双表中选择插入表
- java - 使用休眠将 LocalDateTime 持久化为 sqlite-db 中的 ISO-String
- java - 对于相同的属性,Intellij 显示其中一个未使用
- javascript - 如何在前端使用“%”修复 DecimalField 上的 WTForm 验证错误(“不是有效的十进制值”)?
- python - 使用 Python 创建 Nifi PutSQL 处理器