MongoDB:4-MongoDB的索引和查询分析(explain)

本文涉及的产品
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
简介: MongoDB:4-MongoDB的索引和查询分析(explain)

索引

  1. 索引就是用来加速查询的。
  2. 数据库索引与书籍的索引类似:
  3. 有了索引就不需要翻遍整本书,数据库则可以直接在索引中查找,使得查找速度能提高几个数量级。
  4. 在索引中找到条目以后,就可以直接跳转到目标文档的位置。
  5. 索引是特殊的数据结构,索引存储在一个易于遍历读取的数据集合中,
  6. 索引是对数据库表中一列或多列的值进行排序的一种结构


  • 创建普通索引,使用命令 db.collection.ensureIndex({key:1})
  • 创建唯一索引,使用命令 db.collection.ensureIndex({key:1},{unique:true})
  1. 语法中 Key 值为你要创建的索引字段,
  2. 1为指定按升序创建索引,如果你想按降序来创建索引指定为-1即可。
  • ensureIndex() 接收可选参数,可选参数列表如下:
Parameter Type Description
background Boolean 建索引过程会阻塞其它数据库操作,background可指定以后台方式创建索引,即增加 "background" 可选参数。 "background" 默认值为false
unique Boolean 建立的索引是否唯一。指定为true创建唯一索引。默认值为false.
name string 索引的名称。如果未指定,MongoDB的通过连接索引的字段名和排序顺序生成一个索引名称。
dropDups Boolean 在建立唯一索引时是否删除重复记录,指定 true 创建唯一索引。默认值为 false.
sparse Boolean 对文档中不存在的字段数据不启用索引;这个参数需要特别注意,如果设置为true的话,在索引字段中不会查询出不包含对应字段的文档.。默认值为 false.
expireAfterSeconds integer 指定一个以秒为单位的数值,完成 TTL设定,设定集合的生存时间。
v index version 索引的版本号。默认的索引版本取决于mongod创建索引时运行的版本。
weights document 索引权重值,数值在 1 到 99,999 之间,表示该索引相对于其他索引字段的得分权重。
default_language string 对于文本索引,该参数决定了停用词及词干和词器的规则的列表。 默认为英语
language_override string 对于文本索引,该参数指定了包含在文档中的字段名,语言覆盖默认的language,默认值为 language.


  • 在后台创建索引:
  1. db.values.ensureIndex({open: 1, close: 1}, {background: true})

  • 查看关于索引的相关信息,使用命令 db.collection.stats()
  • 查看查询使用索引的情况,使用命令   db.collection.find({key:value}).explain()
  • 删除索引,使用命令 db.collection.dropIndex({key:1})
  • 删除集合,也会将集合中的索引全部删除


MongoDB 查询分析

  1. MongoDB 查询分析
  2. MongoDB 查询分析可以确保我们建议的索引是否有效,是查询语句性能分析的重要工具。
  3. MongoDB 查询分析常用函数有:explain() 和 hint()。


使用 explain()

  • explain 操作提供了查询信息,使用索引及查询统计等。有利于我们对索引的优化。
  • 接下来我们在 users 集合中创建 nameage的索引:
  1. db.users.ensureIndex({name:1,age:1})

现在在查询语句中使用 explain :

  1. db.users.find({name:"ghost"}).explain()

以上的 explain() 查询返回如下结果:

  1. /* 1 */
  2. {
  3.    "queryPlanner" : {
  4.        "plannerVersion" : 1,
  5.        "namespace" : "mongotest.users",
  6.        "indexFilterSet" : false,
  7.        "parsedQuery" : {
  8.            "name" : {
  9.                "$eq" : "ghost"
  10.            }
  11.        },
  12.        "winningPlan" : {
  13.            "stage" : "FETCH",
  14.            "inputStage" : {
  15.                "stage" : "IXSCAN",
  16.                "keyPattern" : {
  17.                    "name" : 1.0,
  18.                    "age" : 1.0
  19.                },
  20.                "indexName" : "name_1_age_1",
  21.                "isMultiKey" : false,
  22.                "multiKeyPaths" : {
  23.                    "name" : [],
  24.                    "age" : []
  25.                },
  26.                "isUnique" : false,
  27.                "isSparse" : false,
  28.                "isPartial" : false,
  29.                "indexVersion" : 2,
  30.                "direction" : "forward",
  31.                "indexBounds" : {
  32.                    "name" : [
  33.                        "[\"ghost\", \"ghost\"]"
  34.                    ],
  35.                    "age" : [
  36.                        "[MinKey, MaxKey]"
  37.                    ]
  38.                }
  39.            }
  40.        },
  41.        "rejectedPlans" : []
  42.    },
  43.    "serverInfo" : {
  44.        "host" : "kf-PC",
  45.        "port" : 27017,
  46.        "version" : "3.4.9",
  47.        "gitVersion" : "876ebee8c7dd0e2d992f36a848ff4dc50ee6603e"
  48.    },
  49.    "ok" : 1.0
  50. }

本人使用的是Moongdb3.4.9版本,Mongodb3.0版本的explain返回结果和以前的版本有很大的不同,介于Mongodb3.0的许多优秀特色,将3.0版本的返回分成了3个不同层面:

  • queryPlanner:查询计划的选择器,首先进行查询分析,最终选择一个winningPlan,是explain返回的默认层面。
  • executionStats:为执行统计层面,返回winningPlan的统计结果
  • allPlansExecution:为返回所有执行计划的统计,包括rejectedPlan

所以:我们在查询优化的时候,只需要关注queryPlanner, executionStats即可,


因为queryPlanner为我们选择出了winningPlan, 而executionStats为我们统计了winningPlan的所有关键数据。

  1. explain.queryPlanner: queryPlanner的
  2. explain.queryPlanner.namespace:该值返回的是该query所查询的表
  3. explain.queryPlanner.indexFilterSet:针对该query是否有indexfilter
  4. explain.queryPlanner.winningPlan:查询优化器针对该query所返回的最优执行计划的详细内容。
  5. explain.queryPlanner.winningPlan.stage:最优执行计划的stage,这里返回是FETCH,可以理解为通过返回的index位置去检索具体的文档(stage有多个模式,将在后文中进行详解)。
  6. Explain.queryPlanner.winningPlan.inputStage:用来描述子stage,并且为其父stage提供文档和索引关键字。
  7. explain.queryPlanner.winningPlan.stage的child stage,此处是IXSCAN,表示进行的是index scanning。
  8. explain.queryPlanner.winningPlan.keyPattern:所扫描的index内容,此处是did:1,status:1,modify_time: -1与scid : 1
  9. explain.queryPlanner.winningPlan.indexName:winning plan所选用的index。
  10. explain.queryPlanner.winningPlan.isMultiKey是否是Multikey,此处返回是false,如果索引建立在array上,此处将是true
  11. explain.queryPlanner.winningPlan.direction:此query的查询顺序,此处是forward,如果用了.sort({modify_time:-1})将显示backward。
  12. explain.queryPlanner.winningPlan.indexBounds:winningplan所扫描的索引范围,如果没有制定范围就是[MaxKey, MinKey],这主要是直接定位到mongodb的chunck中去查找数据,加快数据读取。
  13. explain.queryPlanner.rejectedPlans:其他执行计划(非最优而被查询优化器reject的)的详细返回,其中具体信息与winningPlan的返回中意义相同,故不在此赘述。


stage的类型的意义

  1. mongodb的文档中列出了前4种类型,还有一些没有列出来,但是会比较常见,这里一并解释一下。
  2. COLLSCAN :全表扫描
  3. IXSCAN:索引扫描
  4. FETCH::根据索引去检索指定document
  5. SHARD_MERGE:各个分片返回数据进行merge
  6. SORT:表明在内存中进行了排序(与前期版本的scanAndOrder:true一致)
  7. SORT_MERGE:表明在内存中进行了排序后再合并
  8. LIMIT:使用limit限制返回数
  9. SKIP:使用skip进行跳过
  10. IDHACK:针对_id进行查询
  11. SHARDING_FILTER:通过mongos对分片数据进行查询
  12. COUNT:利用db.coll.count()之类进行count运算
  13. COUNTSCAN:count不使用用Index进行count时的stage返回
  14. COUNT_SCAN:count使用了Index进行count时的stage返回
  15. SUBPLA:未使用到索引的$or查询的stage返回
  16. TEXT:使用全文索引进行查询时候的stage返回
  17. 附:explain查询结果解析官方文档:
  18. https://docs.mongodb.org/v3.0/reference/explain-results/


使用 hint()

  • 虽然MongoDB查询优化器一般工作的很不错,但是也可以使用 hint 来强制 MongoDB 使用一个指定的索引
  • 这种方法某些情形下会提升性能。 一个有索引的 collection 并且执行一个多字段的查询(一些字段已经索引了)。


如下查询实例指定了使用 nameage索引字段来查询:

  1. db.users.find({name:"ghost"}).hint({name:1,age:1})


可以使用 explain() 函数来分析以上查询:

  1. db.users.find({name:"ghost"}).hint({name:1,age:1}).explain()


参考来源: http://blog.chinaunix.net/uid-26904464-id-5611821.html

参考来源:http://www.runoob.com/mongodb/mongodb-analyzing-queries.html



相关实践学习
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
目录
相关文章
|
2月前
|
监控 NoSQL MongoDB
MongoDB数据库的索引管理技巧
【8月更文挑战第20天】MongoDB数据库的索引管理技巧
47 1
|
3月前
|
NoSQL Java API
MongoDB 强制使用索引 hint
MongoDB 强制使用索引 hint
90 3
|
7天前
|
存储 NoSQL 关系型数据库
MongoDB中的索引操作总结
这篇文章总结了MongoDB中索引的概念、创建方法、常见操作指令、限制以及索引对查询效率的影响。
22 2
|
7天前
|
SQL NoSQL JavaScript
04 MongoDB各种查询操作 以及聚合操作总结
文章全面总结了MongoDB中的查询操作及聚合操作,包括基本查询、条件筛选、排序以及聚合管道的使用方法和实例。
20 0
|
2月前
|
JSON NoSQL MongoDB
MongoDB Schema设计实战指南:优化数据结构,提升查询性能与数据一致性
【8月更文挑战第24天】MongoDB是一款领先的NoSQL数据库,其灵活的文档模型突破了传统关系型数据库的限制。它允许自定义数据结构,适应多样化的数据需求。设计MongoDB的Schema时需考虑数据访问模式、一致性需求及性能因素。设计原则强调简洁性、查询优化与合理使用索引。例如,在构建博客系统时,可以通过精心设计文章和用户的集合结构来提高查询效率并确保数据一致性。正确设计能够充分发挥MongoDB的优势,实现高效的数据管理。
41 3
|
2月前
|
存储 NoSQL MongoDB
【掌握MongoDB】轻松精通MongoDB查询,从基础到高级一网打尽!
【8月更文挑战第24天】在数据驱动的时代,数据库的性能与灵活性对企业至关重要。MongoDB作为一种高性能、无模式的文档数据库,为开发者提供了灵活的数据存储方案。尤其在处理半结构化或多变数据时展现出强大优势。本文重点介绍MongoDB中的查询操作,包括基本查询、条件查询、复杂查询以及字段选择、排序和限制等功能。通过掌握这些基本查询技巧,开发者能够有效从MongoDB中检索数据,支持复杂的业务逻辑。
49 1
|
2月前
|
监控 NoSQL MongoDB
mongodb查询100万数据如何查询快速
综上,提高MongoDB百万级数据的查询性能需要综合多项技术,并在实际应用中不断调优和实践。理解数据的特征,合理设计索引,优化查询语句,在数据访问、管理上遵循最佳的实践,这样才能有效地管理和查询大规模的数据集合。
122 1
|
2月前
|
存储 NoSQL 关系型数据库
4-MongoDB索引知识
MongoDB通过索引提升查询效率,避免全集合扫描。索引采用B树结构存储部分数据集,按字段值排序,支持快速匹配与排序查询。主要类型包括:单字段索引,支持升序/降序;复合索引,字段顺序影响排序逻辑;地理空间索引,适用于坐标数据查询;文本索引,用于搜索字符串内容;哈希索引,用于散列分片,仅支持等值查询。更多详情参见官方文档:[MongoDB索引指南](https://docs.mongodb.com/manual/indexes/)。
|
2月前
|
C# 微服务 Windows
模块化革命:揭秘WPF与微服务架构的完美融合——从单一职责原则到事件聚合器模式,构建高度解耦与可扩展的应用程序
【8月更文挑战第31天】本文探讨了如何在Windows Presentation Foundation(WPF)应用中借鉴微服务架构思想,实现模块化设计。通过将WPF应用分解为独立的功能模块,并利用事件聚合器实现模块间解耦通信,可以有效提升开发效率和系统可维护性。文中还提供了具体示例代码,展示了如何使用事件聚合器进行模块间通信,以及如何利用依赖注入进一步提高模块解耦程度。此方法不仅有助于简化复杂度,还能使应用更加灵活易扩展。
61 0
|
2月前
|
安全 C# 数据安全/隐私保护
WPF安全加固全攻略:从数据绑定到网络通信,多维度防范让你的应用固若金汤,抵御各类攻击
【8月更文挑战第31天】安全性是WPF应用程序开发中不可或缺的一部分。本文从技术角度探讨了WPF应用面临的多种安全威胁及防护措施。通过严格验证绑定数据、限制资源加载来源、实施基于角色的权限管理和使用加密技术保障网络通信安全,可有效提升应用安全性,增强用户信任。例如,使用HTML编码防止XSS攻击、检查资源签名确保其可信度、定义安全策略限制文件访问权限,以及采用HTTPS和加密算法保护数据传输。这些措施有助于全面保障WPF应用的安全性。
40 0
下一篇
无影云桌面