MongoDB执行计划分析详解(1)

正文

queryPlanner

queryPlanner是现版本explain的默认模式,queryPlanner模式下并不会去真正进行query语句查询,而是针对query语句进行执行计划分析并选出winning plan。

{
        "queryPlanner" : {
                "plannerVersion" : 1,
                "namespace" : "game_db.game_user",
                "indexFilterSet" : false,
                "parsedQuery" : {
                        "w" : {
                                "$eq" : 1
                        }
                },
                "winningPlan" : {
                        "stage" : "FETCH",
                        "inputStage" : {
                                "stage" : "IXSCAN",
                                "keyPattern" : {
                                        "w" : 1,
                                        "n" : 1
                                },
                                "indexName" : "w_1_n_1",
                                "isMultiKey" : false,
                                "direction" : "forward",
                                "indexBounds" : {
                                        "w" : [
                                                "[1.0, 1.0]"
                                        ],
                                        "n" : [
                                                "[MinKey, MaxKey]"
                                        ]
                                }
                        }
                },
                "rejectedPlans" : [
                        {
                                "stage" : "FETCH",
                                "inputStage" : {
                                        "stage" : "IXSCAN",
                                        "keyPattern" : {
                                                "w" : 1,
                                                "v" : 1
                                        },
                                        "indexName" : "w_1_v_1",
                                        "isMultiKey" : false,
                                        "direction" : "forward",
                                        "indexBounds" : {
                                                "w" : [
                                                        "[1.0, 1.0]"
                                                ],
                                                "v" : [
                                                        "[MinKey, MaxKey]"
                                                ]
                                        }
                                }
                        }
                ]
        },

先来看queryPlanner模式的各个返回意义。

explain.queryPlanner

queryPlanner的返回。

explain.queryPlanner.namespace

顾名思义,该值返回的是该query所查询的表。

explain.queryPlanner.indexFilterSet

针对该query是否有indexfilter(会在后文进行详细解释)。

explain.queryPlanner.winningPlan

查询优化器针对该query所返回的最优执行计划的详细内容。

explain.queryPlanner.winningPlan.stage

最优执行计划的stage,这里返回是FETCH,可以理解为通过返回的index位置去检索具体的文档(stage有数个模式,将在后文中进行详解)。

explain.queryPlanner.winningPlan.inputStage

explain.queryPlanner.winningPlan.stage的child stage,此处是IXSCAN,表示进行的是index scanning。

explain.queryPlanner.winningPlan.keyPattern

所扫描的index内容,此处是w:1与n:1。

explain.queryPlanner.winningPlan.indexName

winning plan所选用的index。

explain.queryPlanner.winningPlan.isMultiKey

是否是Multikey,此处返回是false,如果索引建立在array上,此处将是true。

explain.queryPlanner.winningPlan.direction

此query的查询顺序,此处是forward,如果用了.sort({w:-1})将显示backward。

explain.queryPlanner.winningPlan.indexBounds

winningplan所扫描的索引范围,此处查询条件是w:1,使用的index是w与n的联合索引,故w是[1.0,1.0]而n没有指定在查询条件中,故是[MinKey,MaxKey]。

explain.queryPlanner.rejectedPlans

其他执行计划(非最优而被查询优化器reject的)的详细返回,其中具体信息与winningPlan的返回中意义相同,故不在此赘述。

executionStats

executionStats的返回中多了如下:

  "executionStats" : {
                "executionSuccess" : true,
                "nReturned" : 29861,
                "executionTimeMillis" : 23079,
                "totalKeysExamined" : 29861,
                "totalDocsExamined" : 29861,
                "executionStages" : {
                        "stage" : "FETCH",
                        "nReturned" : 29861,
                        "executionTimeMillisEstimate" : 22685,
                        "works" : 29862,
                        "advanced" : 29861,
                        "needTime" : 0,
                        "needFetch" : 0,
                        "saveState" : 946,
                        "restoreState" : 946,
                        "isEOF" : 1,
                        "invalidates" : 0,
                        "docsExamined" : 29861,
                        "alreadyHasObj" : 0,
                        "inputStage" : {
                                "stage" : "IXSCAN",
                                "nReturned" : 29861,
                                "executionTimeMillisEstimate" : 70,
                                "works" : 29862,
                                "advanced" : 29861,
                                "needTime" : 0,
                                "needFetch" : 0,
                                "saveState" : 946,
                                "restoreState" : 946,
                                "isEOF" : 1,
                                "invalidates" : 0,
                                "keyPattern" : {
                                        "w" : 1,
                                        "n" : 1
                                },
                                "indexName" : "w_1_n_1",
                                "isMultiKey" : false,
                                "direction" : "forward",
                                "indexBounds" : {
                                        "w" : [
                                                "[1.0, 1.0]"
                                        ],
                                        "n" : [
                                                "[MinKey, MaxKey]"
                                        ]
                                },
                                "keysExamined" : 29861,
                                "dupsTested" : 0,
                                "dupsDropped" : 0,
                                "seenInvalidated" : 0,
                                "matchTested" : 0
                        }
                }
        },

executionStats模式中,我们主要需要注意的返回有如下几个

executionStats.executionSuccess

是否执行成功

executionStats.nReturned

查询的返回条数

executionStats.executionTimeMillis

整体执行时间

executionStats.totalKeysExamined

索引扫描次数

executionStats.totalDocsExamined

document扫描次数

以上几个非常好理解,我们就不在这里详述,后文的案例中会有分析。

executionStats.executionStages.stage

这里是FETCH去扫描对于documents

executionStats.executionStages.nReturned

由于是FETCH,所以这里该值与executionStats.nReturned一致

executionStats.executionStages.docsExamined

与executionStats.totalDocsExamined一致

executionStats.inputStage中的与上述理解方式相同

还有一些文档中没有描述的返回如:

“works” : 29862,

“advanced” : 29861,

“isEOF” : 1,

这些值都会在explan之初初始化:

mongo/src/mongo/db/exec/plan_stats.h

struct CommonStats {
    CommonStats(const char* type)
        : stageTypeStr(type),
          works(0),
          yields(0),
          unyields(0),
          invalidates(0),
          advanced(0),
          needTime(0),
          needYield(0),
          executionTimeMillis(0),
          isEOF(false) {}

以works为例,查看源码中发现,每次操作会加1,且会把执行时间记录在executionTimeMillis中。

mongo/src/mongo/db/exec/fetch.cpp

         ++_commonStats.works;

        // Adds the amount of time taken by work() to executionTimeMillis.
        ScopedTimer timer(&_commonStats.executionTimeMillis);

而在查询结束EOF,works又会加1,advanced不加。

mongo/src/mongo/db/exec/eof.cpp

PlanStage::StageState EOFStage::work(WorkingSetID* out) {
    ++_commonStats.works;
    // Adds the amount of time taken by work() to executionTimeMillis.
    ScopedTimer timer(&_commonStats.executionTimeMillis);
    return PlanStage::IS_EOF;
}

故正常的返回works会比nReturned多1,这时候isEOF为true(1):

mongo/src/mongo/db/exec/eof.cpp

bool EOFStage::isEOF() {
    return true;
}

unique_ptr<PlanStageStats> EOFStage::getStats() {
    _commonStats.isEOF = isEOF();
    return make_unique<PlanStageStats>(_commonStats, STAGE_EOF);
}

advanced的返回值在命中的时候+1,在skip,eof的时候不会增加如:

mongo/src/mongo/db/exec/skip.cpp

if (PlanStage::ADVANCED == status) {
        // If we‘re still skipping results...
        if (_toSkip > 0) {
            // ...drop the result.
            --_toSkip;
            _ws->free(id);
            ++_commonStats.needTime;
            return PlanStage::NEED_TIME;
        }

        *out = id;
        ++_commonStats.advanced;
        return PlanStage::ADVANCED;
时间: 2024-10-27 05:15:40

MongoDB执行计划分析详解(1)的相关文章

MySQL 执行计划explain详解

MySQL 执行计划explain详解 2015-08-10 13:56:27 分类: MySQL explain命令是查看查询优化器如何决定执行查询的主要方法.这个功能有局限性,并不总会说出真相,但它的输出是可以获取的最好信息,值得花时间去了解,因为可以学习到查询是如何执行的. 调用EXPLAIN 在select之前添加explain,mysql会在查询上设置一个标记,当执行查询计划时,这个标记会使其返回关于执行计划中每一步的信息,而不是执行它.它会返回一行或多行信息,显示出执行计划中的每一部

SQL Server 执行计划操作符详解(2)——串联(Concatenation )

本文接上文:SQL Server 执行计划操作符详解(1)--断言(Assert) 前言: 根据计划,本文开始讲述另外一个操作符串联(Concatenation),读者可以根据这个词(中英文均可)先幻想一下是干嘛的.其实还是挺直观,就是把东西连起来,那么下面我们来看看到底连什么?怎么连?什么时候连? 简介: 串联操作符既是物理操作符,也是逻辑操作符,在中文版SQL Server的图形化执行计划中称为"串联",在其他格式及英文版本中称为"Concatenation".

SQL Server 执行计划操作符详解(1)——断言(Assert

前言: 很多很多地方对于语句的优化,一般比较靠谱的回复即使--把执行计划发出来看看.当然那些只看语句就说如何如何改代码,我一直都是拒绝的,因为这种算是纯蒙.根据本人经验,大量的性能问题单纯从语句来看很难发现瓶颈,同一个语句,由于环境的不同,差距非常大,所以比较合适的还是分析执行计划. 那么对于执行计划,一般使用图形化执行计划就差不多了,但是用过的人也有一些疑惑,里面的图标(称为操作符)并不非常直观.所以从本文开始,会整理一些不怎么常见但由比较重要的操作符并进行解释,对于那些表扫描.索引扫描.聚集

MYSQL EXPLAIN执行计划命令详解(支持更新中)

本文来自我的github pages博客http://galengao.github.io/ 即www.gaohuirong.cn 摘要: 本篇是根据官网中的每个一点来翻译.举例.验证的:英语不好,所以有些话语未必准确,请自行查看官网,若有些点下面没有例子的是因为当时一下子没有想出那么多来,如果大家有遇上好的例子,欢迎在下面留言我持续更新 查看执行计划的关键EXPLAIN 版本MYSQL5.6,用到的库是官网例子sakila,自行下载导入 由于要把每个点都翻译出来,还需要举例,所以需要一定的时间

Django之HttpServer服务器分析详解

大家知道,软件的正向工程,是从软件的需求获取开始,大概经历需求分析,概要分析,领域分析,设计分析,详细设计,代码实现,部署,实施这几个步骤,最终交付给用户使用.而在某些时候,比如某个软件产品是用PHP开发的,因为某些原因,我们想移植到JAVA平台去.或者某公司看到某个软件的市场前景很好,想COPY它的主要功能,然后经过加工润色后推出一个具有相同功能,更好用户体验或更多功能的软件.或者单纯的以研究软件的结构.设计思想为目的.基于这些需求,我们需要逆向工程.正向工程是一个从过程导出结果的步骤,而逆向

Mysql Join语法解析与性能分析详解

一.Join语法概述 join 用于多表中字段之间的联系,语法如下: ... FROM table1 INNER|LEFT|RIGHT JOIN table2 ON conditiona table1:左表:table2:右表. JOIN 按照功能大致分为如下三类: INNER JOIN(内连接,或等值连接):取得两个表中存在连接匹配关系的记录. LEFT JOIN(左连接):取得左表(table1)完全记录,即是右表(table2)并无对应匹配记录. RIGHT JOIN(右连接):与 LEF

[转]Linux操作系统tcpdump抓包分析详解

PS:tcpdump是一个用于截取网络分组,并输出分组内容的工具,简单说就是数据包抓包工具.tcpdump凭借强大的功能和灵活的截取策略,使其成为Linux系统下用于网络分析和问题排查的首选工具. tcpdump提供了源代码,公开了接口,因此具备很强的可扩展性,对于网络维护和入侵者都是非常有用的工具.tcpdump存在于基本的Linux系统中,由于它需要将网络界面设置为混杂模式,普通用户不能正常执行,但具备root权限的用户可以直接执行它来获取网络上的信息.因此系统中存在网络分析工具主要不是对本

MongoDB各种查询操作详解

这篇文章主要介绍了MongoDB各种查询操作详解,包括比较查询.关联查询.数组查询等,需要的朋友可以参考下 一.find操作 MongoDB中使用find来进行查询,通过指定find的第一个参数可以实现全部和部分查询. 1.查询全部 空的查询文档{}会匹配集合的全部内容.如果不指定查询文档,默认就是{}. 2.部分查询 3.键的筛选 键的筛选是查询时只返回自己感兴趣的键值,通过指定find的第二个参数来实现.这样可以节省传输的数据量,又能节省客户端解码文档的时间和内存消耗. 查询时,数据库所关心

wav文件格式分析详解

wav文件格式分析详解 文章转载自:http://blog.csdn.net/BlueSoal/article/details/932395 一.综述    WAVE文件作为多媒体中使用的声波文件格式之一,它是以RIFF格式为标准的.RIFF是英文Resource Interchange File Format的缩写,每个WAVE文件的头四个字节便是"RIFF".    WAVE文件是由若干个Chunk组成的.按照在文件中的出现位置包括:RIFF WAVEChunk, Format C