Mongo优化——explain函数的基本使用

本文涉及的产品
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
简介: 当数据量不大时,查询语句随便写,只要实现逻辑功能即可;但当数据量大到一定程度时,可能以前的方法就不可行了,因为一是查询数度变慢,更有甚者可能因数据量大而导致查询失败。解决这种问题最简单的方法是添加索引并利用好这些索引。可以通过explain函数来分析:1、在建索引前数据请求情况2、创建索引后数据请求是否有变好。现在就来看看explain相关知识。

简介

当数据量不大时,查询语句随便写,只要实现逻辑功能即可;但当数据量大到一定程度时,可能以前的方法就不可行了,因为一是查询数度变慢,更有甚者可能因数据量大而导致查询失败。解决这种问题最简单的方法是添加索引并利用好这些索引。可以通过explain函数来分析:1、在建索引前数据请求情况2、创建索引后数据请求是否有变好。现在就来看看explain相关知识。

explain请求格式

请求格式

格式:

> db.collection.find().explain(verbose)

参数verbose有以下3种值:

1. queryPlanner(默认)
    MongoDB运行查询优化器对当前的查询进行评估并选择一个最佳的查询计划
2. executionStats
    mongoDB运行查询优化器对当前的查询进行评估并选择一个最佳的查询计划进行执行
    在执行完毕后返回这个最佳执行计划执行完成时的相关统计信息
3. allPlansExecution
    即按照最佳的执行计划执行以及列出统计信息
    如果有多个查询计划,还会列出这些非最佳执行计划部分的统计信息

verbose==queryPlanner(默认)

说明: MongoDB运行查询优化器对当前的查询进行评估并选择一个最佳的查询计划

> db.my_collection.explain().find({"_id":"zhaoweiguo"})
[
    {
        queryPlanner: {
            winningPlan: {
                stage: "SINGLE_SHARD",
                shards: [
                    {
                        ...
                        winningPlan: {      // 这儿是选择的最佳查询计划
                            ...
                        },
                        rejectedPlans: [    // 这是其他的查询计划
                            {
                                ...
                            },
                            {
                                ...
                            }
                        ]
                    }
                ]
            }
        }
        ...
    }
]

verbose==executionStats

mongoDB运行查询优化器对当前的查询进行评估并选择一个最佳的查询计划进行执行

在执行完毕后返回这个最佳执行计划执行完成时的相关统计信息

> db.my_collection.explain("executionStats").find({"_id":"zhaoweiguo"})
[
    {
        queryPlanner: {         // 同queryPlanner查询一样
            ...
        },
        executionStats: {         // 同queryPlanner查询不同之处: 具体执行并统计信息
            nReturned: 3,
            executionTimeMillis: 2,
            totalKeysExamined: 3,
            totalDocsExamined: 3,
            executionStages: {      // 返回最佳执行计划执行完成时的相关统计信息(与queryPlanner的不同点)
                ...
            },
        }
        ...
    }
]

verbose==allPlansExecution

即按照最佳的执行计划执行以及列出统计信息

如果有多个查询计划,还会列出这些非最佳执行计划部分的统计信息

> db.my_collection.explain("allPlansExecution").find({"_id":"zhaoweiguo"})
> 
[
    {
        queryPlanner: {         // 同queryPlanner查询一样
            ...
        },
        executionStats: {
            nReturned: 3,
            executionTimeMillis: 2,
            totalKeysExamined: 3,
            totalDocsExamined: 3,
            executionStages: {    // 同executionStats查询一样
                ...
            },
            allPlansExecution: [    // 同executionStats查询不同之处: rejectedPlans中的也统计信息
                {
                  ...     // rejectedPlans中第1条的统计信息
                },
                {
                  ...     // rejectedPlans中第2条的统计信息
                }
                ...
            ]
        }
        ...
    }
]

常见的stage说明

常见的执行步骤stage:

COLLSCAN 文档扫描(Collection Scan)即:未命中索引,全表扫描
IXSCAN 索引扫描
FETCH 根据索引去检索指定 document
SORT 内存排序(表明在内存中进行了排序)

COUNT 进行了 count 运算
COUNT_SCAN: count 使用了 Index 进行 count 时的 stage 返回
COUNTSCAN: count 不使用 Index 进行 count 时的 stage 返回

PROJECTION: 字段映射(限定返回字段时候 stage 的返回)

OR $or 查询子句全部命中索引时出现
LIMIT 结果集条数限制(使用 limit 限制返回数)
SKIP 从结果集中跳过部分条目(使用 skip 进行跳过)

IDHACK: 针对_id 进行查询

SINGLE_SHARD:   数据在一个shard中
SHARD_MERGE:    数据分布在多个shard中,合并各分片结果
SHARDING_FILTER: 通过 mongos 对分片数据进行查询

TEXT: 使用全文索引进行查询时候的 stage 返回

SUBPLA: 未使用到索引的 $or 查询的 stage 返回

其他executionStats说明

字段说明:

nReturned:执行返回的文档数
executionTimeMillis: 执行时间(ms)
totalKeysExamined:索引扫描条数
totalDocsExamined:文档扫描条数
executionStages:执行步骤

更多帮助

获取 explain 的支持的运算方法:

> db.my_collection.explain().help()
[
    [
        Explainable operations,
        .aggregate(...) - explain an aggregation operation,
        .count(...) - explain a count operation,
        .distinct(...) - explain a distinct operation,
        .find(...) - get an explainable query,
        .findAndModify(...) - explain a findAndModify operation,
        .remove(...) - explain a remove operation,
        .update(...) - explain an update operation,
        Explainable collection methods,
        .getCollection(),
        .getVerbosity(),
        .setVerbosity(verbosity)
    ]
]

获取 explain().find() 支持的运算方法:

> db.collection.explain().find().help()
[
    [
        Explain query modifiers,
        .addOption(n),
        .batchSize(n),
        .comment(comment),
        .collation(collationSpec),
        .count(),
        .hint(hintSpec),
        .limit(n),
        .maxTimeMS(n),
        .max(idxDoc),
        .min(idxDoc),
        .readPref(mode, tagSet),
        .showDiskLoc(),
        .skip(n),
        .sort(sortSpec)
    ]
]

完整实例说明

[
    {
        queryPlanner: {
            mongosPlannerVersion: 1,
            winningPlan: {
                stage: "SINGLE_SHARD",
                shards: [
                    {   // 如果是分片表,这儿会展示多个shard
                        shardName: "d-2ze07ec75d921fa4",
                        namespace: "mydb.my_collection",
                        parsedQuery: {    
                            $and: [
                                {
                                    is_delete: {
                                        $eq: "0"
                                    }
                                },
                                {
                                    is_read: {
                                        $eq: "0"
                                    }
                                },
                                {
                                    source_id: {
                                        $eq: "xxxxxxxx91138f6c5138e52fd749xxxxxxx"
                                    }
                                },
                                {
                                    user_id: {
                                        $eq: "xxxxxxx874aa1a0343448xxxxxx"
                                    }
                                }
                            ]
                        },
                        winningPlan: {      // 对查询评估并选择一个最佳的查询计划
                            stage: "LIMIT",
                            limitAmount: 3,
                            inputStage: {
                                stage: "FETCH",
                                inputStage: {
                                    stage: "IXSCAN",
                                    indexName: "is_delete_1_user_id_1_time_created_-1",
                                    ...
                                }
                            }
                        },
                        rejectedPlans: [    // 其他非最佳的查询计划
                            {
                                stage: "SORT",
                                sortPattern: {
                                    time_created: -1
                                },
                                limitAmount: 3,
                                inputStage: {
                                    stage: "SORT_KEY_GENERATOR",
                                    inputStage: {
                                        stage: "FETCH",
                                        inputStage: {
                                            stage: "IXSCAN",
                                            indexName: "source_id_1_user_id_1_is_read_1_is_delete_1",
                                            ...
                                        }
                                    }
                                }
                            },
                            {
                                stage: "SORT",
                                sortPattern: {
                                    time_created: -1
                                },
                                limitAmount: 3,
                                inputStage: {
                                    stage: "SORT_KEY_GENERATOR",
                                    inputStage: {
                                        stage: "FETCH",
                                        inputStage: {
                                            stage: "IXSCAN",
                                            indexName: "source_id_1",
                                        }
                                    }
                                }
                            }
                        ]
                    }
                ]
            }
        },
        executionStats: {           // 运行相关统计信息
            nReturned: 3,               // 返回数据条数: 3条
            executionTimeMillis: 2,     // 执行时间: 3ms
            totalKeysExamined: 3,       // 索引扫描条数: 3条
            totalDocsExamined: 3,       // 文档扫描条数: 3条
            executionStages: {      // 最佳执行计划执行完成时的相关统计信息(即上一级最终的数据)
                stage: "SINGLE_SHARD",
                nReturned: 3,
                executionTimeMillis: 2,
                totalKeysExamined: 3,
                totalDocsExamined: 3,
                totalChildMillis: NumberLong(1),
                shards: [
                    {   // 如果是分片表,这儿会展示多个shard
                        shardName: "d-2ze07ec75d921fa4",    // 使用了哪个shard
                        executionSuccess: true,
                        executionStages: {
                            stage: "LIMIT",
                            nReturned: 3,
                            executionTimeMillisEstimate: 0,
                            limitAmount: 3,
                            inputStage: {
                                stage: "FETCH",
                                nReturned: 3,
                                executionTimeMillisEstimate: 0,
                                inputStage: {
                                    stage: "IXSCAN",
                                    nReturned: 3,
                                    executionTimeMillisEstimate: 0,
                                    indexName: "is_delete_1_user_id_1_time_created_-1",
                                    ...
                                }
                            }
                        }
                    }
                ]
            },
            allPlansExecution: [      // 非最佳执行计划执行的相关统计信息
                {
                    shardName: "d-2ze07ec75d921fa4",
                    allPlans: [
                        {             // 执行计划1
                            nReturned: 3,
                            executionTimeMillisEstimate: 0,
                            totalKeysExamined: 3,
                            totalDocsExamined: 3,
                            executionStages: {
                                stage: "LIMIT",
                                nReturned: 3,
                                executionTimeMillisEstimate: 0,
                                limitAmount: 3,
                                inputStage: {
                                    stage: "FETCH",
                                    nReturned: 3,
                                    executionTimeMillisEstimate: 0,
                                    inputStage: {
                                        stage: "IXSCAN",
                                        nReturned: 3,
                                        executionTimeMillisEstimate: 0,
                                        indexName: "is_delete_1_user_id_1_time_created_-1",
                                        ...
                                    }
                                }
                            }
                        },
                        {             // 执行计划2
                            nReturned: 0,
                            executionTimeMillisEstimate: 0,
                            totalKeysExamined: 2,
                            totalDocsExamined: 2,
                            executionStages: {
                                stage: "SORT",
                                nReturned: 0,
                                executionTimeMillisEstimate: 0,
                                sortPattern: {
                                    time_created: -1
                                },
                                memUsage: 985,
                                memLimit: 33554432,
                                limitAmount: 3,
                                inputStage: {
                                    stage: "SORT_KEY_GENERATOR",
                                    nReturned: 2,
                                    executionTimeMillisEstimate: 0,
                                    inputStage: {
                                        stage: "FETCH",
                                        nReturned: 2,
                                        executionTimeMillisEstimate: 0,
                                        inputStage: {
                                            stage: "IXSCAN",
                                            nReturned: 2,
                                            executionTimeMillisEstimate: 0,
                                            indexName: "source_id_1_user_id_1_is_read_1_is_delete_1",
                                        }
                                    }
                                }
                            }
                        },
                        {             // 执行计划3
                            nReturned: 0,
                            executionTimeMillisEstimate: 0,
                            totalKeysExamined: 2,
                            totalDocsExamined: 2,
                            executionStages: {
                                stage: "SORT",
                                nReturned: 0,
                                executionTimeMillisEstimate: 0,
                                sortPattern: {
                                    time_created: -1
                                },
                                memUsage: 985,
                                memLimit: 33554432,
                                limitAmount: 3,
                                inputStage: {
                                    stage: "SORT_KEY_GENERATOR",
                                    nReturned: 2,
                                    executionTimeMillisEstimate: 0,
                                    inputStage: {
                                        stage: "FETCH",
                                        nReturned: 2,
                                        executionTimeMillisEstimate: 0,
                                        inputStage: {
                                            stage: "IXSCAN",
                                            nReturned: 2,
                                            executionTimeMillisEstimate: 0,
                                            indexName: "source_id_1",
                                        }
                                    }
                                }
                            }
                        }
                    ]
                }
            ]
        },
        ok: 1.0,
        operationTime: Timestamp(1603252218,345),
        $clusterTime: {
            clusterTime: Timestamp(1603252218,365),
            signature: {
                hash: BinData(0,"My+HyRMvT0NEYLU+VLaYeGVu7eQ="),
                keyId: NumberLong(6836642960822501517)
            }
        }
    }
]

参考

相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。   相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
目录
相关文章
|
3月前
|
JSON 关系型数据库 MySQL
MySQL 8.0常用函数汇总与应用实例
这些函数只是MySQL 8.0提供的众多强大功能的一部分。通过结合使用这些函数,你可以有效地处理各种数据,优化数据库查询,并提高应用程序的性能和效率。
78 3
|
存储 SQL 缓存
MySQL高阶知识点(一):SQL语句是怎么执行的
Server 层包括连接器、查询缓存、分析器、优化器、执行器等,涵盖 MySQL 的大多数核心服务功能,以及所有的内置函数(如日期、时间、数学和加密函数等),所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图等。 而存储引擎层负责数据的存储和提取。其架构模式是插件式的,支持 InnoDB、MyISAM、Memory 等多个存储引擎。现在最常用的存储引擎是 InnoDB,它从 MySQL 5.5.5 版本开始成为了默认存储引擎。
5196 7
MySQL高阶知识点(一):SQL语句是怎么执行的
|
SQL 存储 缓存
mysql进阶优化篇04——深入JOIN语句的底层原理
mysql进阶优化篇04——深入JOIN语句的底层原理
|
SQL 存储 搜索推荐
explain使用方法及结果分析
explain使用方法及结果分析
135 0
|
关系型数据库 MySQL
【MySQL】(十二)MySQL函数大全及用法示例1
【MySQL】(十二)MySQL函数大全及用法示例1
456 0
|
关系型数据库 MySQL Unix
【MySQL】(十二)MySQL函数大全及用法示例2
【MySQL】(十二)MySQL函数大全及用法示例2
182 0
|
SQL 关系型数据库 MySQL
MySQL 子查询优化源码分析
# 子查询定义 在一个完整的查询语句中包含的子查询块被称为子查询。通常情况下,我们可以将出现在SELECT、WHERE和HAVING语法中的子查询块称为嵌套子查询,出现在FROM语法后的子查询块称为内联视图或派生表。 本篇文章将会结合源码介绍在MySQL中针对子查询的几种优化策略。 # 子查询在执行计划中的表示 ![temp.jpg](https://ata2-img.oss-cn
339 0
MySQL 子查询优化源码分析
|
SQL 关系型数据库 MySQL
MySQL中SELECT语句简单使用
MySQL中SELECT语句简单使用最近开始复习mysql,查漏补缺吧。 关于mysql1.MySQL不区分大小写,但是在MySQL 4.1及之前的版本中,数据库名、表名、列名这些标识符默认是区分大小写的;在之后的版本中默认不区分大小写。
860 0