MongoDB笔记03-MongoDB索引
文章目录
- 一、前言
- 1.1 概述
- 1.2 MongoDB索引使用B-Tree还是B+Tree?
- 1.3 B 树和 B+ 树的对比
- 1.4 总结
- 二、索引的类型
- 2.1 单字段索引
- 2.2 复合索引
- 2.3 其他索引
- 三、索引的管理操作
- 3.1 索引的查看
- 3.2 索引的创建
- 3.2.1 单字段索引
- 3.2.2 复合索引
- 3.3 索引的移除
- 3.3.1 指定索引的移除
- 3.3.2 所有索引的移除
- 四、 索引的使用
- 4.1 执行计划
- 4.2 涵盖的查询
一、前言
1.1 概述
- 索引支持在MongoDB中高效地执行查询。如果没有索引,MongoDB必须执行全集合扫描,即扫描集合中的每个文档,以选择与查询语句匹配的文档。这种扫描全集合的查询效率是非常低的,特别在处理大量的数据时,查询可以要花费几十秒甚至几分钟,这对网站的性能是非常致命的。
- 如果查询存在适当的索引,MongoDB可以使用该索引限制必须检查的文档数。
- 索引是特殊的数据结构,它以易于遍历的形式存储集合数据集的一小部分。索引存储特定字段或一组字段的值,按字段值排序。索引项的排序支持有效的相等匹配和基于范围的查询操作。此外,MongoDB还可以使用索引中的排序返回排序结果。
- 官网文档:https://docs.mongodb.com/manual/indexes/
1.2 MongoDB索引使用B-Tree还是B+Tree?
MongoDB索引在查看资料的时候有些地方说使用是B-Tree,有些地方说是B+Tree)
因此使用db.serverStatus()查看默认使用的存储引擎
> db.serverStatus()
..."storageEngine" : {"name" : "wiredTiger","supportsCommittedReads" : true,"supportsSnapshotReadConcern" : true,"readOnly" : false,"persistent" : true},
...
可以看到MongoDB使用的存储引擎是wiredTiger,而wiredTiger使用的是 B+ 树作为其存储结构。
而之所以有B-Tree还是B+Tree的争论,可能是从 MongoDb 3.2 版本开始,其使用了 WiredTiger 作为其默认的存储引擎。而MongoDb 3.2 版本之前可能使用 B 树作为存储的数据结构。
相关文档:https://www.mongodb.com/zh-cn/docs/manual/core/wiredtiger/
1.3 B 树和 B+ 树的对比
B 树
内部节点:内部节点既存储键(keys),也存储值(values)。
叶子节点:叶子节点存储键值对。
适用场景:适合点查(精确匹配)和少量范围查询。
B+ 树
内部节点:内部节点只存储键(keys),不存储值(values)。
叶子节点:所有值(values)都存储在叶子节点中,叶子节点之间形成一个有序的链表。
适用场景:适合范围查询和顺序访问
1.4 总结
B树的树内存储数据,因此查询单条数据的时候,B树的查询效率不固定,最好的情况是O(1)。我们可以认为在做单一数据查询的时候,使用B树平均性能更好。但是,由于B树中各节点之间没有指针相邻,因此B树不适合做一些数据遍历操作。
B+树的数据只出现在叶子节点上,因此在查询单条数据的时候,查询速度非常稳定。因此,在做单一数据的查询上,其平均性能并不如B树。但是,B+树的叶子节点上有指针进行相连,因此在做数据遍历的时候,只需要对叶子节点进行遍历即可,这个特性使得B+树非常适合做范围查询。
参考文章:
https://www.cnblogs.com/rjzheng/p/12316685.html
https://zhuanlan.zhihu.com/p/519658576
二、索引的类型
2.1 单字段索引
MongoDB支持在文档的单个字段上创建用户定义的升序/降序索引,称为单字段索引(Single Field Index)。
对于单个字段索引和排序操作,索引键的排序顺序(即升序或降序)并不重要,因为MongoDB可以在任何方向上遍历索引
2.2 复合索引
MongoDB还支持多个字段的用户定义索引,即复合索引(Compound Index)。
复合索引中列出的字段顺序具有重要意义。例如,如果复合索引由 { userid: 1, score: -1 } 组成,则索引首先按userid正序排序,然后在每个userid的值内,再在按score倒序排序。
2.3 其他索引
地理空间索引(Geospatial Index)、文本索引(Text Indexes)、哈希索引(Hashed Indexes)。
地理空间索引(Geospatial Index)
为了支持对地理空间坐标数据的有效查询,MongoDB提供了两种特殊的索引:返回结果时使用平面几何的二维索引和返回结果时使用球面几何的二维球面索引。
文本索引(Text Indexes)
MongoDB提供了一种文本索引类型,支持在集合中搜索字符串内容。这些文本索引不存储特定于语言的停止词(例如“the”、“a”、“or”),而将集合中的词作为词干,只存储根词。
哈希索引(Hashed Indexes)
为了支持基于散列的分片,MongoDB提供了散列索引类型,它对字段值的散列进行索引。这些索引在其范围内的值分布更加随机,但只支持相等匹配,不支持基于范围的查询。
注意:
当查询条件比较多,同时要提高性能时,使用复合索引
索引也是一个小集合,会占用空间,如果创建很多索引,会影响插入效率。
三、索引的管理操作
3.1 索引的查看
说明:
返回一个集合中的所有索引的数组。
语法:
db.collection.getIndexes()
注意:该语法命令运行要求是MongoDB 3.0+
【示例】
查看comment集合中所有的索引情况
> db.comment.getIndexes()
[{"v" : 2,"key" : {"_id" : 1},"name" : "_id_","ns" : "articledb.comment"}
]
结果中显示的是默认 _id 索引。
默认_id索引:
MongoDB在创建集合的过程中,在 _id 字段上创建一个唯一的索引,默认名字为 id ,该索引可防止客户端插入两个具有相同值的文档,您不能在_id字段上删除此索引。
注意:该索引是唯一索引,因此值不能重复,即 _id 值不能重复的。在分片集群中,通常使用 _id 作为片键
3.2 索引的创建
说明:
在集合上创建索引。
语法:
db.collection.createIndex(keys, options)
参数:
参数 | 类型 | 说明 |
---|---|---|
keys | document | 包含字段和值对的文档,其中字段是索引键,值描述该字段的索引类型。对于字段上的升序索引,请指定值1;对于降序索引,请指定值-1。比如: {字段:1或-1} ,其中1 为指定按升序创建索引,如果你想按降序来创建索引指定为 -1 即可。另外,MongoDB支持几种不同的索引类型,包括文本、地理空间和哈希索引。 |
options | document | 可选。包含一组控制索引创建的选项的文档。. |
注意:
在 3.0.0 版本前创建索引方法为 db.collection.ensureIndex() ,之后的版本使用了 db.collection.createIndex() 方法,ensureIndex() 还能用,但只是 createIndex() 的别名。
3.2.1 单字段索引
示例:对 userid 字段建立索引:
> db.comment.createIndex({userid:1})
{"createdCollectionAutomatically" : false,"numIndexesBefore" : 1,"numIndexesAfter" : 2,"ok" : 1
}
> db.comment.getIndexes()
[{"v" : 2,"key" : {"_id" : 1},"name" : "_id_","ns" : "articledb.comment"},{"v" : 2,"key" : {"userid" : 1},"name" : "userid_1","ns" : "articledb.comment"}
]
建立索引时的参数:按升序创建索引
在mongodb-compass中也可以看到创建的索引
3.2.2 复合索引
对 userid 和 nickname 同时建立复合(Compound)索引:
> db.comment.createIndex({userid:1,nickname:-1})
{"createdCollectionAutomatically" : false,"numIndexesBefore" : 2,"numIndexesAfter" : 3,"ok" : 1
}
> db.comment.getIndexes()
[{"v" : 2,"key" : {"_id" : 1},"name" : "_id_","ns" : "articledb.comment"},{"v" : 2,"key" : {"userid" : 1},"name" : "userid_1","ns" : "articledb.comment"},{"v" : 2,"key" : {"userid" : 1,"nickname" : -1},"name" : "userid_1_nickname_-1","ns" : "articledb.comment"}
]
mongodb-compass中查看
3.3 索引的移除
说明:可以移除指定的索引,或移除所有索引
3.3.1 指定索引的移除
语法:
db.collection.dropIndex(index)
参数:
参数 | 类型 | 说明 |
---|---|---|
index | string or document | 指定要删除的索引。可以通过索引名称或索引规范文档指定索引。若要删除文本索引,请指定索引名称。 |
【示例】
删除 comment 集合中 userid 字段上的升序索引:
> db.comment.dropIndex({userid:1})
{ "nIndexesWas" : 3, "ok" : 1 }> db.comment.getIndexes()
[{"v" : 2,"key" : {"_id" : 1},"name" : "_id_","ns" : "articledb.comment"},{"v" : 2,"key" : {"userid" : 1,"nickname" : -1},"name" : "userid_1_nickname_-1","ns" : "articledb.comment"}
]
删除复合索引
> db.comment.dropIndex("userid_1_nickname_-1"){ "nIndexesWas" : 2, "ok" : 1 }> db.comment.getIndexes()
[{"v" : 2,"key" : {"_id" : 1},"name" : "_id_","ns" : "articledb.comment"}
]
3.3.2 所有索引的移除
语法:
db.comment.dropIndexes()
【示例】
删除 comment 集合中所有索引
> db.comment.dropIndexes()
{"nIndexesWas" : 1,"msg" : "non-_id indexes dropped for collection","ok" : 1
}
> db.comment.getIndexes()
[{"v" : 2,"key" : {"_id" : 1},"name" : "_id_","ns" : "articledb.comment"}
]
注意: _id 的字段的索引是无法删除的,只能删除非 _id 字段的索引。
四、 索引的使用
4.1 执行计划
分析查询性能(Analyze Query Performance)通常使用执行计划(解释计划、Explain Plan)来查看查询的情况,如查询耗费的时间、是否基于索引查询等。
那么,通常,我们想知道,建立的索引是否有效,效果如何,都需要通过执行计划查看。
语法:
db.collection.find(query,options).explain(options)
【示例】
查看根据userid查询数据的情况:
> db.comment.find({userid:"1003"}).explain()
{"queryPlanner" : {"plannerVersion" : 1,"namespace" : "articledb.comment","indexFilterSet" : false,"parsedQuery" : {"userid" : {"$eq" : "1003"}},"winningPlan" : {"stage" : "COLLSCAN","filter" : {"userid" : {"$eq" : "1003"}},"direction" : "forward"},"rejectedPlans" : [ ]},"serverInfo" : {"host" : "SKY-20211222SVF","port" : 27017,"version" : "4.0.12","gitVersion" : "5776e3cbf9e7afe86e6b29e22520ffb6766e95d4"},"ok" : 1
}
注意: "stage" : "COLLSCAN", 表示全集合扫描
下面对userid建立索引
> db.comment.createIndex({userid:1})
{"createdCollectionAutomatically" : false,"numIndexesBefore" : 1,"numIndexesAfter" : 2,"ok" : 1
}
> db.comment.find({userid:"1003"}).explain()
{"queryPlanner" : {"plannerVersion" : 1,"namespace" : "articledb.comment","indexFilterSet" : false,"parsedQuery" : {"userid" : {"$eq" : "1003"}},"winningPlan" : {"stage" : "FETCH","inputStage" : {"stage" : "IXSCAN","keyPattern" : {"userid" : 1},"indexName" : "userid_1","isMultiKey" : false,"multiKeyPaths" : {"userid" : [ ]},"isUnique" : false,"isSparse" : false,"isPartial" : false,"indexVersion" : 2,"direction" : "forward","indexBounds" : {"userid" : ["[\"1003\", \"1003\"]"]}}},"rejectedPlans" : [ ]},"serverInfo" : {"host" : "SKY-20211222SVF","port" : 27017,"version" : "4.0.12","gitVersion" : "5776e3cbf9e7afe86e6b29e22520ffb6766e95d4"},"ok" : 1
}
compass查看:
4.2 涵盖的查询
Covered Queries
当查询条件和查询的投影仅包含索引字段时,MongoDB直接从索引返回结果,而不扫描任何文档或将文档带入内存。 这些覆盖的查询可以非常有效。(类似mysql不用回表扫描)
更多:https://docs.mongodb.com/manual/core/query-optimization/#read-operations-covered-query
【示例】
> db.comment.find({userid:"1003"},{userid:1,_id:0})
{ "userid" : "1003" }
{ "userid" : "1003" }
> db.comment.find({userid:"1003"},{userid:1,_id:0}).explain()
{"queryPlanner" : {"plannerVersion" : 1,"namespace" : "articledb.comment","indexFilterSet" : false,"parsedQuery" : {"userid" : {"$eq" : "1003"}},"winningPlan" : {"stage" : "PROJECTION","transformBy" : {"userid" : 1,"_id" : 0},"inputStage" : {"stage" : "IXSCAN","keyPattern" : {"userid" : 1},"indexName" : "userid_1","isMultiKey" : false,"multiKeyPaths" : {"userid" : [ ]},"isUnique" : false,"isSparse" : false,"isPartial" : false,"indexVersion" : 2,"direction" : "forward","indexBounds" : {"userid" : ["[\"1003\", \"1003\"]"]}}},"rejectedPlans" : [ ]},"serverInfo" : {"host" : "SKY-20211222SVF","port" : 27017,"version" : "4.0.12","gitVersion" : "5776e3cbf9e7afe86e6b29e22520ffb6766e95d4"},"ok" : 1
}
compass查看:
全部文章:
MongoDB笔记01-概念与安装
MongoDB笔记02-MongoDB基本常用命令
MongoDB笔记03-MongoDB索引
MongoDB笔记04-SpringBoot整合MongoDB
相关文章:

MongoDB笔记03-MongoDB索引
文章目录 一、前言1.1 概述1.2 MongoDB索引使用B-Tree还是BTree?1.3 B 树和 B 树的对比1.4 总结 二、索引的类型2.1 单字段索引2.2 复合索引2.3 其他索引 三、索引的管理操作3.1 索引的查看3.2 索引的创建3.2.1 单字段索引3.2.2 复合索引 3.3 索引的移除3.3.1 指定索…...

Docker基础(一)
Docker 简介 常用命令 镜像 #搜索镜像 docker search nginx #下载镜像 docker pull nginx #下载指定版本镜像 docker pull nginx:1.26.0 #查看所有镜像 docker images #删除指定id的镜像 docker rmi e784f4560448 # 删除多个镜像 docker rmi bde7d154a67f 94543a6c1aef e784…...
解决 IntelliJ IDEA Maven 项目 JDK 版本自动变为 1.5 的问题
一、问题描述 在使用 IntelliJ IDEA 创建 Maven 项目时,经常会遇到一个问题:项目的默认编译版本被设置为 JDK 1.5,即使系统中安装的是更高版本的 JDK。这不仅会导致编译时出现警告,还可能引起兼容性问题。每次手动修改编译版本后…...

SDL事件相关
文章目录 事件相关的函数和数据结构用户自定义事件代码相关: 事件相关的函数和数据结构 SDL_WaitEvent :等待一个事件SDL_PushEvent 发送一个事件SDL_PumpEvents(): 将硬件设备产生的时间放入事件队列 ,用于读取事件,在调用该函数之前&#…...

探索App Intents:让你的应用与Siri无缝互动的新方式
苹果推出了一个新框架——App Intents,使开发者可以在iOS 18.2、macOS 15.2等平台上集成Siri和Apple Intelligence,实现对应用内容的读取和操作。 App Intents使应用的功能和内容能无缝融入系统体验中,例如Siri、Spotlight搜索、快捷指令和小…...
冒泡排序法
编写程序实现冒泡排序。 相关知识 为了完成本关任务,要了解冒泡法排序的算法思想: 对所有相邻记录的关键字值进行比较,如果是逆序则将其交换,最终达到有序化,其处理过程为: 将整个待排序的记录序列划分成…...

MATLAB 将fig格式另存为可编辑的eps格式,但乱码问题解决
fig格式图像正常,但通过手动导出后的eps格式图像导入到AI中会乱码,如下图所示 一、主要问题应该是: 文件名中的字符和格式受到了操作系统和文件系统的限制,具体而言是 figure 的Name 属性中包含了特殊字体或字符(如逗号ÿ…...

Hadoop:单节点配置YARN
目录 一、Hadoop YARN介绍 二、单节点配置YARN 2.1 配置yarn-site.xml 文件 2.2 配置 mapred-site.xml 文件 2.3 启动 Hadoop 和 YARN 2.4 浏览器访问 三、YARN的常用命令 3.1 启动和停止 YARN 3.2 查看和管理应用程序 3.3 查看和管理节点 3.4 查看和管理队列 3.5 …...
【前端】Svelte:组件间通信
在 Svelte 中,组件间的通信主要通过 props 和事件机制来实现。父组件可以向子组件传递数据,子组件也可以通过事件将信息反馈给父组件。在本教程中,我们将深入了解 Svelte 的组件通信机制,包括 props 和事件的使用方法、事件监听、…...

数学建模-----假设性检验引入+三个经典应用场景(三种不同的假设性检验类型)
文章目录 1.假设检验的过程1.1问题的提出1.2证据的引入1.4做出结论 2.案例二:汽车引擎排放2.1进行假设2.2假设检验的类型2.3抽样分布的类型2.4单尾(双尾)检验2.5t检验 3.案例三:特鲁普效应3.1统计显著和效果显著3.2心理学现象3.3进…...
Unity——对RectTransform进行操作
文章目录 前言在Unity中对RectTransform进行操作是处理UI布局和动画的关键部分。下面是一些常见的操作及其代码示例,可以帮助你在脚本中灵活地控制UI元素的位置、大小和锚点。 一、获取和设置位置二、获取和设置大小1.设置大小(Size Delta) 三…...

使用jmeter查询项目数据库信息,保存至本地txt或excel文件1108
知识点1:使用jmeter把项目数据库的数据导出,并使用jmeter导出数据库的数据 步骤1:使用jmeter把项目数据库的数据导出 (1)测试计划-添加- 线程组setUp线程组 setUp线程组:添加-配置元件-JDBC Connection …...
ubuntu 22.04 server 安装 mysql 5.7.40 更改 datadir 目录 LTS
ubuntu 22.04 server 安装 mysql 5.7.40 更改 datadir 目录 LTS 参考 ubuntu 22.04 server 安装 mysql 5.7.40 LTS https://blog.csdn.net/wowocpp/article/details/143564015 vip Ubuntu中修改MySQL5.7数据存储路径 https://www.cnblogs.com/jiaojiner/p/15236639.html u…...

网站架构知识之Ansible进阶2(day023)
1.include文件 应用场景: 1个ansible剧本内容过多,涉及到多个play(- host:web),可读性变弱,不方便调试。 于是人们想出把单个大的剧本拆分为多个小的剧本, 多个小的剧本可以通过include功能合并使用。 使用方法,书写好对应的剧本文件&#…...
Java 中的 Function:让转换逻辑更灵活
文章目录 1. Function 基础:简化转换逻辑2. 组合 Function:实现多步转换3. 配合 Stream 使用:简化数据转换4. 自定义 Function,封装复杂转换5. 使用 identity() 提供默认转换6. 结合 Optional,实现动态数据转换7. 用于…...

10. java基础知识(下)
文章目录 一、一带而过二、字符串类型String1. 简单了解2. 关于结束符\03. 自动类型转换与强制类型转换 三、API文档与import导包1. API文档2. import导包 四、java中的数组1. 创建2. 遍历3. 补充4. Arrays类① 简单介绍② 练习 五、方法的重载六、规范约束七、内容出处 一、一…...
kafka 在Linux安上的装部署
一、前言 Kafka 是一个分布式流处理平台,在大数据领域有着广泛的应用。在 Linux 系统上安装部署 Kafka 可以为我们搭建高效的数据处理环境。本教程将详细介绍在 Linux 中安装和部署 Kafka 的步骤。 二、准备工作 2.1 系统要求 确保你的 Linux 系统已经安装并配置…...
kill-start系统进程的研究
kill/start系统进程的研究 声明:内容的只是方便各位师傅学习知识,以下网站只涉及学习内容,其他的都与本人无关,切莫逾越法律红线,否则后果自负。 目录 kill/start系统进程的研究Windows系统进程简介特点系统进程 tas…...
【系统架构设计师】2024年下半年真题论文: 论面向服务的架构设计(包括解题思路和参考素材)
更多内容请见: 备考系统架构设计师-专栏介绍和目录 文章目录 真题题目(2024年下半年 试题1)解题思路论文素材参考面向服务的架构(SOA)概念和特征面向服务的架构关键技术面向服务的架构设计原则面向服务的架构设计案例分析SOA设计面临的挑战与应对策略真题题目(2024年下半…...

吴恩达深度学习笔记:序列模型(Sequence Models) 1.1-1.2
目录 第五门课 序列模型(Sequence Models)第一周 循环序列模型(Recurrent Neural Networks)1.1 为什么选择序列模型?(Why Sequence Models?)1.2 数学符号(Notation) 第五门课 序列模型(Sequenc…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...

免费PDF转图片工具
免费PDF转图片工具 一款简单易用的PDF转图片工具,可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件,也不需要在线上传文件,保护您的隐私。 工具截图 主要特点 🚀 快速转换:本地转换,无需等待上…...

华为OD机考-机房布局
import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...

iview框架主题色的应用
1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题,无需引入,直接可…...

【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信 BLE Mesh协议的拓扑结构 定向转发机制
目录 节点的功能承载层(GATT/Adv)局限性: 拓扑关系定向转发机制定向转发意义 CG 节点的功能 节点的功能由节点支持的特性和功能决定。所有节点都能够发送和接收网格消息。节点还可以选择支持一个或多个附加功能,如 Configuration …...

Ubuntu系统多网卡多相机IP设置方法
目录 1、硬件情况 2、如何设置网卡和相机IP 2.1 万兆网卡连接交换机,交换机再连相机 2.1.1 网卡设置 2.1.2 相机设置 2.3 万兆网卡直连相机 1、硬件情况 2个网卡n个相机 电脑系统信息,系统版本:Ubuntu22.04.5 LTS;内核版本…...

在 Visual Studio Code 中使用驭码 CodeRider 提升开发效率:以冒泡排序为例
目录 前言1 插件安装与配置1.1 安装驭码 CodeRider1.2 初始配置建议 2 示例代码:冒泡排序3 驭码 CodeRider 功能详解3.1 功能概览3.2 代码解释功能3.3 自动注释生成3.4 逻辑修改功能3.5 单元测试自动生成3.6 代码优化建议 4 驭码的实际应用建议5 常见问题与解决建议…...

热门Chrome扩展程序存在明文传输风险,用户隐私安全受威胁
赛门铁克威胁猎手团队最新报告披露,数款拥有数百万活跃用户的Chrome扩展程序正在通过未加密的HTTP连接静默泄露用户敏感数据,严重威胁用户隐私安全。 知名扩展程序存在明文传输风险 尽管宣称提供安全浏览、数据分析或便捷界面等功能,但SEMR…...