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)
            }
        }
    }
]

参考

目录
相关文章
|
NoSQL 索引
MongoDB查询优化:从 10s 到 10ms
本文是我前同事付秋雷最近遇到到一个关于MongoDB执行计划选择的问题,非常有意思,在探索源码之后,他将整个问题搞明白并整理分享出来。付秋雷(他的博客)曾是Tair(阿里内部用得非常官方的KV存储系统)的核心开发,目前就职于蘑菇街。
|
安全 大数据 测试技术
Mongodb亿级数据量的性能测试比较完整收藏一下
原文地址:http://www.cnblogs.com/lovecindywang/archive/2011/03/02/1969324.html 进行了一下Mongodb亿级数据量的性能测试,分别测试如下几个项目: (所有插入都是单线程进行,所有读取都是多线程进行) 1) 普通插入性能 (插...
4384 0
|
NoSQL MongoDB 存储
MongoDB 一致性模型设计与实现
本文源自阅读了 MongoDB 于 VLDB 19 上发表的 [Tunable Consistency in MongoDB](http://www.vldb.org/pvldb/vol12/p2071-schultz.pdf) 论文之后,在内部所做的分享(分享 PPT 见文末)。现在把分享的内容整理成此文,并且补充了部分在之前的分享中略过的细节,以及在分享中没有提及的 MongoDB Causa
2022 0
MongoDB 一致性模型设计与实现
|
NoSQL MongoDB 数据库
MongoDB日志浅析
MongoDB 日志
7027 0
|
NoSQL Redis 监控
redis-shake数据同步&迁移&备份导入导出工具使用介绍
redis-shake是阿里云Redis&MongoDB团队开源的用于redis数据同步的工具。
71509 4
redis-shake数据同步&迁移&备份导入导出工具使用介绍
|
编译器 Go API
go generate指南:代码自动生成
go generate指南:代码自动生成
3592 0
|
消息中间件 存储 分布式计算
Mac系统安装Kafka 3.x及可视化工具
Mac系统安装Kafka 3.x及可视化工具
5061 0
|
SQL 关系型数据库 MySQL
|
NoSQL Shell MongoDB
一日一技:单机单节点 MongoDB 为什么删除数据后不释放空间?
一日一技:单机单节点 MongoDB 为什么删除数据后不释放空间?
1043 0