mongodb查询操作分析

本文涉及的产品
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
简介: 背景mongodb 提供了类sql的数据查询及操作方式,同时也包含了聚合操作、索引等多个机制;按以往的经验,不当的库表操作或索引模式往往会造成许多问题,如查询操作缓慢、数据库吞吐量低下、CPU或磁盘IO飙升等问题。

背景

mongodb 提供了类sql的数据查询及操作方式,同时也包含了聚合操作、索引等多个机制;
按以往的经验,不当的库表操作或索引模式往往会造成许多问题,如查询操作缓慢、数据库吞吐量低下、CPU或磁盘IO飙升等问题。
因此在应用开发过程中,有必要对DB操作进行审视,尤其是关键业务或复杂条件查询。mongodb 提供了explain方法可以让我们
对 DB查询语句进行分析,提前分析潜在的瓶颈。

查询计划

mongodb 通过查询计划(QueryPlan)描述一个查询语句的执行过程,而通常一个查询操作可能对应多组查询计划。
这些查询计划通过选举机制产生最优计划,作为最终的执行方案。此外mongodb 还提供了查询计划的缓存机制,如下图:

https://docs.mongodb.com/manual/_images/query-planner-diagram.bakedsvg.svimg_c5ff5ff395f9b505328386dbd818ebbe.png

Diagram of query planner logic

查询操作被映射到一个查询模型(query shape),模型中会包含条件(predicate)、排序(sort)、投影(projection)的定义;
以查询模型作为Key查找已存在的Plan缓存,在找到缓存的下一步仍进一步评估查询性能,若性能评估结果未达标,则 mongodb会淘汰缓存并进入查询计划生成阶段。
每一个计划生成阶段都会包含:

  • 产生候选计划;
  • 评估优选计划;
  • 竞选最优计划;
  • 创建缓存;

在产生最优计划之后,查询执行器将执行当前计划并产生最终结果。

explain 操作

通过下面的语句,可以对当前查询计划展开分析

db.T_FooData.find({
"appId":"s5WrMmrJV_8RBJG17FSVoY995Kga",
"nodeType":"SENSOR",
"creationTime":{
    $gte : ISODate("2017-08-08T10:34:33.125Z"),
    $lt : ISODate("2017-08-08T12:34:33.125Z")
    }
}).explain("executionStats")

输出结果

{
    "queryPlanner" : {
        "plannerVersion" : 1,
        "namespace" : "db.T_FooData",
        "indexFilterSet" : false,
        "parsedQuery" : {
            "$and" : [
                {
                    "appId" : {
                        "$eq" : "s5WrMmrJV_8RBJG17FSVoY995Kga"
                    }
                },
                {
                    "nodeType" : {
                        "$eq" : "SENSOR"
                    }
                },
                {
                    "creationTime" : {
                        "$lt" : ISODate("2017-08-08T12:34:33.125Z")
                    }
                },
                {
                    "creationTime" : {
                        "$gte" : ISODate("2017-08-08T10:34:33.125Z")
                    }
                }
            ]
        },
        "winningPlan" : { ... },
        "rejectedPlans" : [ ... ],
    },
    "executionStats" : {
        "executionSuccess" : true,
        "nReturned" : 62848,
        "executionTimeMillis" : 3058,
        "totalKeysExamined" : 1510833,
        "totalDocsExamined" : 1510833,
        "executionStages" : { ... }

    },
    "serverInfo" : {
        "host" : "NB3000W_MongoDB_01",
        "port" : 50001,
        "version" : "3.4.7",
        "gitVersion" : "4249c1d2b5999ebbf1fdf3bc0e0e3b3ff5c0aaf2"
    },
    "ok" : 1,
    "$gleStats" : {
        "lastOpTime" : Timestamp(1504498101, 1),
        "electionId" : ObjectId("7fffffff0000000000000001")
    }
}

结果说明

  • queryPlanner 描述当前的查询计划;
  • queryPlanner.namespace 描述当前的集合命名空间,{db}.{collectionName}
  • queryPlanner.indexFilterSet 是否设置了indexFilter,Filter决定了查询优化器对于某个查询将如何使用索引
  • queryPlanner.parsedQuery 解析后的查询信息
  • queryPlanner.winningPlan 最优计划
  • queryPlanner.rejectPlans 拒绝的计划列表

  • executionStats 执行过程统计,捕获计划在执行过程中的相关信息
  • executionStats.executionSuccess 是否执行成功
  • executionStats.nReturned 返回条目数量
  • executionStats.executionTimeMilis 执行时间(ms)
  • executionStats.totalKeysExamined 索引检测条目
  • executionStats.totalDocsExamined 文档检测条目
  • executionStats.executionStages 执行阶段详情

explain 模式

mongodb 为 explain 操作提供了几种模式:

  • queryPlanner 默认的模式,仅进行查询计划分析,无法输出执行过程统计;
  • executionStats 执行模式,在查询计划分析后,将执行winningPlan并统计过程信息;
  • allPlansExecution 全计划执行模式,将执行所有计划(包括rejectPlans),并返回过程统计信息;
    executionStats.allPlansExecution 包含了所有计划(除winningPlan之外)的执行过程统计信息

执行计划详解

执行计划将整个过程分解为多个阶段,阶段(stage)以树状结构组织,这点与执行过程是匹配的。

stage 分为多种类型,如下:

阶段 描述
COLLSCAN 全表扫描
IXSCAN 索引扫描
FETCH 根据索引去检索指定document
PROJECTION 限定返回字段
SHARD_MERGE 将各个分片返回数据进行merge
SORT 表明在内存中进行了排序
LIMIT 使用limit限制返回数
SKIP 使用skip进行跳过
IDHACK 针对_id进行查询
SHARDING_FILTER 通过mongos对分片数据进行查询
COUNT 利用db.coll.explain().count()之类进行count运算
COUNTSCAN count不使用用Index进行count
COUNT_SCAN count使用了Index进行count
SUBPLA 未使用到索引的$or查询
TEXT 使用全文索引进行查询

winningPlan 样例

"winningPlan" : {
            "stage" : "FETCH",
            "filter" : {
                "$and" : [
                    {
                        "nodeType" : {
                            "$eq" : "GATEWAY"
                        }
                    },
                    {
                        "creationTime" : {
                            "$lt" : ISODate("2017-08-08T12:34:33.125Z")
                        }
                    },
                    {
                        "creationTime" : {
                            "$gte" : ISODate("2017-08-08T10:34:33.125Z")
                        }
                    }
                ]
            },
            "inputStage" : {
                "stage" : "IXSCAN",
                "keyPattern" : {
                    "appId" : 1
                },
                "indexName" : "appId",
                "isMultiKey" : false,
                "isUnique" : false,
                "isSparse" : false,
                "isPartial" : false,
                "indexVersion" : 1,
                "direction" : "forward",
                "indexBounds" : {
                    "appId" : [
                        "[\"s5WrMmrJV_8RBJG17FSVoY995Kga\", \"s5WrMmrJV_8RBJG17FSVoY995Kga\"]"
                    ]
                }
            }
        },

字段说明

属性 描述
winningPlan.stage 最优计划stage,FETCH表示根据索引检索文档
winningPlan.filter 最优计划的过滤器,即查询条件
winningPlan.inputStage 最优计划stage的child stage
winningPlan.inputStage.stage child stage,此处是IXSCAN,表示进行index scanning
winningPlan.inputStage.keyPattern 扫描的索引模式
winningPlan.inputStage.indexName 选用索引名称
winningPlan.inputStage.isMultiKey 是否是Multikey,如果索引建立在array上则为true
winningPlan.inputStage.isSparse 是否稀疏索引
winningPlan.inputStage.isPartial 是否分区索引
winningPlan.inputStage.direction 此query的查询顺序,此处是forward,如果用了.sort({w:-1})将显示backward
winningPlan.inputStage.indexBounds 所扫描的索引范围

过程统计详解

executionStats 样例

"executionStats" : {
        "executionSuccess" : true,
        "nReturned" : 62848,
        "executionTimeMillis" : 3058,
        "totalKeysExamined" : 1510833,
        "totalDocsExamined" : 1510833,
        "executionStages" : {
            "stage" : "FETCH",
            "filter" : {
                "$and" : [
                    {
                        "nodeType" : {
                            "$eq" : "GATEWAY"
                        }
                    },
                    {
                        "creationTime" : {
                            "$lt" : ISODate("2017-08-08T12:34:33.125Z")
                        }
                    },
                    {
                        "creationTime" : {
                            "$gte" : ISODate("2017-08-08T10:34:33.125Z")
                        }
                    }
                ]
            },
            "nReturned" : 62848,
            "executionTimeMillisEstimate" : 2765,
            "works" : 1510834,
            "advanced" : 62848,
            "needTime" : 1447985,
            "needYield" : 0,
            "saveState" : 11807,
            "restoreState" : 11807,
            "isEOF" : 1,
            "invalidates" : 0,
            "docsExamined" : 1510833,
            "alreadyHasObj" : 0,
            "inputStage" : {
                "stage" : "IXSCAN",
                "nReturned" : 1510833,
                "executionTimeMillisEstimate" : 792,
                "works" : 1510834,
                "advanced" : 1510833,
                "needTime" : 0,
                "needYield" : 0,
                "saveState" : 11807,
                "restoreState" : 11807,
                "isEOF" : 1,
                "invalidates" : 0,
                "keyPattern" : {
                    "appId" : 1
                },
                "indexName" : "appId",
                "isMultiKey" : false,
                "isUnique" : false,
                "isSparse" : false,
                "isPartial" : false,
                "indexVersion" : 1,
                "direction" : "forward",
                "indexBounds" : {
                    "appId" : [
                        "[\"s5WrMmrJV_8RBJG17FSVoY995Kga\", \"s5WrMmrJV_8RBJG17FSVoY995Kga\"]"
                    ]
                },
                "keysExamined" : 1510833,
                "dupsTested" : 0,
                "dupsDropped" : 0,
                "seenInvalidated" : 0
            }
        }
}

字段说明

属性 描述
executionStats.executionSuccess 是否执行成功
executionStats.nReturned 返回条目数量
executionStats.executionTimeMilis 执行时间(ms)
executionStats.totalKeysExamined 索引检测条目
executionStats.totalDocsExamined 文档检测条目
executionStats.executionStages 执行阶段详情,大部分字段继承于winningPlan.inputStage
executionStats.executionStages.stage 执行阶段,FETCH表示根据索引获取文档
executionStats.executionStages.nReturned 阶段返回条目数量
executionStats.executionStages.executionTimeMillisEstimate 阶段执行时间
executionStats.executionStages.docsExamined 阶段中文档检测条目
executionStats.executionStages.works 阶段中扫描任务数
executionStats.executionStages.advanced 阶段中向上提交数量
executionStats.executionStages.needTime 阶段中定位索引位置所需次数
executionStats.executionStages.needYield 阶段中获取锁等待时间
executionStats.executionStages.isEOF 阶段中是否到达流的结束位,对于limit限制符的查询可能为0
executionStats.executionStages.inputStage 执行阶段的子阶段,这里是一个IXSCAN的子过程

参考文档

explain 官方说明

http://www.mongoing.com/eshu_explain1
https://docs.mongodb.com/manual/reference/explain-results/#explain-output

关于explain的几种模式
https://docs.mongodb.com/manual/reference/method/cursor.explain/

理解mongo 的查询行为
https://www.compose.com/articles/explain-explain-understanding-mongo-query-behavior/

mongo的查询缓存
https://docs.mongodb.com/manual/core/query-plans/#index-filters

img_9b09a36f6de95886f52ce82fa1e89c88.jpe

作者: zale

出处: http://www.cnblogs.com/littleatp/, 如果喜欢我的文章,请关注我的公众号

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出 原文链接  如有问题, 可留言咨询.

相关实践学习
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
目录
相关文章
|
7天前
|
存储 NoSQL MongoDB
掌握MongoDB索引优化策略:提升查询效率的关键
在数据库性能调优中,索引是提升查询效率的利器。本文将带你深入了解MongoDB索引的内部工作原理,探讨索引对查询性能的影响,并通过实际案例指导如何针对不同的查询模式建立有效的索引。不仅将涵盖单一字段索引,还会探讨复合索引的使用,以及如何通过分析查询模式和执行计划来优化索引,最终实现查询性能的最大化。
|
2天前
|
SQL NoSQL MongoDB
MongoDB 查询文档
10月更文挑战第15天
6 1
|
4天前
|
人工智能 NoSQL 机器人
MongoDB Atlas与YoMio.AI近乎完美适配:推理更快速、查询更灵活、场景更丰富
随着MongoDB的新发布和革新,YoMio.AI的“闪电式发展”值得期待。
|
1月前
|
SQL NoSQL JavaScript
04 MongoDB各种查询操作 以及聚合操作总结
文章全面总结了MongoDB中的查询操作及聚合操作,包括基本查询、条件筛选、排序以及聚合管道的使用方法和实例。
49 0
|
2月前
|
JSON NoSQL MongoDB
MongoDB Schema设计实战指南:优化数据结构,提升查询性能与数据一致性
【8月更文挑战第24天】MongoDB是一款领先的NoSQL数据库,其灵活的文档模型突破了传统关系型数据库的限制。它允许自定义数据结构,适应多样化的数据需求。设计MongoDB的Schema时需考虑数据访问模式、一致性需求及性能因素。设计原则强调简洁性、查询优化与合理使用索引。例如,在构建博客系统时,可以通过精心设计文章和用户的集合结构来提高查询效率并确保数据一致性。正确设计能够充分发挥MongoDB的优势,实现高效的数据管理。
53 3
|
2月前
|
存储 NoSQL MongoDB
【掌握MongoDB】轻松精通MongoDB查询,从基础到高级一网打尽!
【8月更文挑战第24天】在数据驱动的时代,数据库的性能与灵活性对企业至关重要。MongoDB作为一种高性能、无模式的文档数据库,为开发者提供了灵活的数据存储方案。尤其在处理半结构化或多变数据时展现出强大优势。本文重点介绍MongoDB中的查询操作,包括基本查询、条件查询、复杂查询以及字段选择、排序和限制等功能。通过掌握这些基本查询技巧,开发者能够有效从MongoDB中检索数据,支持复杂的业务逻辑。
54 1
|
2月前
|
监控 NoSQL MongoDB
mongodb查询100万数据如何查询快速
综上,提高MongoDB百万级数据的查询性能需要综合多项技术,并在实际应用中不断调优和实践。理解数据的特征,合理设计索引,优化查询语句,在数据访问、管理上遵循最佳的实践,这样才能有效地管理和查询大规模的数据集合。
170 1
|
2月前
|
C# 微服务 Windows
模块化革命:揭秘WPF与微服务架构的完美融合——从单一职责原则到事件聚合器模式,构建高度解耦与可扩展的应用程序
【8月更文挑战第31天】本文探讨了如何在Windows Presentation Foundation(WPF)应用中借鉴微服务架构思想,实现模块化设计。通过将WPF应用分解为独立的功能模块,并利用事件聚合器实现模块间解耦通信,可以有效提升开发效率和系统可维护性。文中还提供了具体示例代码,展示了如何使用事件聚合器进行模块间通信,以及如何利用依赖注入进一步提高模块解耦程度。此方法不仅有助于简化复杂度,还能使应用更加灵活易扩展。
82 0
|
2月前
|
安全 C# 数据安全/隐私保护
WPF安全加固全攻略:从数据绑定到网络通信,多维度防范让你的应用固若金汤,抵御各类攻击
【8月更文挑战第31天】安全性是WPF应用程序开发中不可或缺的一部分。本文从技术角度探讨了WPF应用面临的多种安全威胁及防护措施。通过严格验证绑定数据、限制资源加载来源、实施基于角色的权限管理和使用加密技术保障网络通信安全,可有效提升应用安全性,增强用户信任。例如,使用HTML编码防止XSS攻击、检查资源签名确保其可信度、定义安全策略限制文件访问权限,以及采用HTTPS和加密算法保护数据传输。这些措施有助于全面保障WPF应用的安全性。
48 0
|
3月前
|
DataWorks NoSQL fastjson
DataWorks操作报错合集之DataX进行MongoDB全量迁移的过程中,DataX的MongoDB Reader插件在初始化阶段找不到Fastjson 2.x版本的类库,该怎么办
DataWorks是阿里云提供的一站式大数据开发与治理平台,支持数据集成、数据开发、数据服务、数据质量管理、数据安全管理等全流程数据处理。在使用DataWorks过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。