首页 > 解决方案 > 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
            }
        }
    }
}

标签: mongodbaggregation-framework

解决方案


总数executionTimeMillis包括一些未在个人计划中考虑的事项,例如:

  • 计划所用时间
    查询计划器评估所有候选索引并计划确定要测试的索引。这可能需要每个候选计划的非零时间,并增加总执行时间。
  • 锁定获取
    计划时只检查索引/文档的一小部分。一旦选择了计划,它就会运行到完成以获取执行统计信息。如果发生其他操作导致查询执行器等待锁,这将增加总时间超过估计
  • 磁盘延迟
    与锁类似,如果在计划阶段从磁盘读取文档非常快,但在执行过程中会慢很多,则总时间将大于估计

可能还有其他考虑因素,如果我想到任何我会在这里添加它们。如果其他人记得我忘记的一个,请随时提出修改建议!


推荐阅读