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)

参数:

参数类型说明
keysdocument包含字段和值对的文档,其中字段是索引键,值描述该字段的索引类型。对于字段上的升序索引,请指定值1;对于降序索引,请指定值-1。比如: {字段:1或-1} ,其中1 为指定按升序创建索引,如果你想按降序来创建索引指定为 -1 即可。另外,MongoDB支持几种不同的索引类型,包括文本、地理空间和哈希索引。
optionsdocument可选。包含一组控制索引创建的选项的文档。.

注意:
在 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)

参数:

参数类型说明
indexstring 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查看:
在这里插入图片描述


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/465597.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

string模拟实现流插入(输出)+流提取(输入)

个人主页:Jason_from_China-CSDN博客 所属栏目:C系统性学习_Jason_from_China的博客-CSDN博客 所属栏目:C知识点的补充_Jason_from_China的博客-CSDN博客 string模拟实现clear 模拟实现clear的目的是在流提取的时候我们清空之前的数据&#x…

C++入门基础知识134—【关于C 库函数 - gmtime()】

成长路上不孤单😊😊😊😊😊😊 【14后😊///C爱好者😊///持续分享所学😊///如有需要欢迎收藏转发///😊】 今日分享关于C 库函数 - gmtime()的相关内容&#xf…

ERP学习笔记-预处理eeglab

第一步:数据格式转化 import data:读取收集到的原始数据文件.vhdr格式 读取后的样子: 将数据保存为.set文件 第二步:通道定位 读取.set文件 Channel locations部分为unknown,表明通道的坐标未知 增加默认的设置 Chan…

查缺补漏----用户上网过程(HTTP,DNS与ARP)

(1)HTTP 来自湖科大计算机网络微课堂: ① HTTP/1.0采用非持续连接方式。在该方式下,每次浏览器要请求一个文件都要与服务器建立TCP连接当收到响应后就立即关闭连接。 每请求一个文档就要有两倍的RTT的开销。若一个网页上有很多引…

谷歌推出全新AI生成游戏玩法 —— 无限生成角色生活模拟游戏“Unbounded”

随着人工智能技术的飞速发展,游戏行业正迎来前所未有的创新。近日,谷歌宣布了一款名为“Unbounded”的新型游戏,这是一款基于生成式AI技术的角色生命模拟游戏,它将为玩家带来前所未有的开放性和互动性体验。 项目概览 项目名称:Unbounded类型:生成式无限游戏(Generati…

论文阅读:DynamicDet: A Unified Dynamic Architecture for Object Detection

论文地址:[2304.05552] DynamicDet: A Unified Dynamic Architecture for Object Detection 代码地址:GitHub - VDIGPKU/DynamicDet: [CVPR 2023] DynamicDet: A Unified Dynamic Architecture for Object Detection 概要 本文提出了一种名为 DynamicD…

关于在GitLab的CI/CD中用docker buildx本地化多架构打包dotnet应用的问题

关于在GitLab的CI/CD中用docker buildx本地化多架构打包dotnet应用的问题 这是一个DevOps综合性问题docker buildx多架构打包.NET应用的问题用QEMU模拟多架构环境打包 这是一个DevOps综合性问题 网络上的方案都是细分的领域,未见一个集成了GitLabdockerdotnet的多架…

翻译工具开发技术笔记:《老挝语翻译通》app支持语音识别翻译功能,怎么提高语音识别的准确度呢?

《老挝语翻译通》app是一款专为老挝语翻译设计的免费工具,支持文本翻译、老挝文OCR文字识别提取、文字转语音。这款工具以其技术优势和用户友好的界面,为用户提供了便捷的老挝语翻译体验。 技术特点 文本翻译:支持双语输入,提供精…

qt QListView详解

1、概述 QListView 是 Qt 框架中的一个视图类,用于展示模型中的数据。它基于 QAbstractItemView,支持多种视图模式,如列表视图(List View)、图标视图(Icon View)等。QListView 是模型/视图框架…

初识C++(上) -- C++的关键字、命名空间、缺省参数以及函数的重载

目录 一、C的关键字(C98) 二、命名空间 1、命名冲突 2、命名空间 2.1 命名空间的定义 (1). 命名空间定义的例子以及命名空间的嵌套: (2). 同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中: 2…

MySQL_客户端工具建库.

前言: 通过前面的学习我们已经了解到什么是数据库,以及数据库是如何安装的,相信大家都已将数据库安装好了,让我们接下来开始新的学习吧!!! 1.MySQL客户端工具 1. MySQL Workbench MySQL :: D…

突破1200°C高温性能极限!北京科技大学用机器学习合成24种耐火高熵合金,室温延展性极佳

在工程应用中,如燃气轮机、核反应堆和航空推进系统,对具备优异高温机械性能的金属合金需求十分旺盛。由于材料熔点的固有限制,传统镍基 (Ni) 高温合金的耐温能力已接近极限。为满足开发高温结构材料的需求,耐火高熵合金 (RHEAs) 于…

leetcode21:合并两个有序列表

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1: 输入:l1 [1,2,4], l2 [1,3,4] 输出:[1,1,2,3,4,4]示例 2: 输入:l1 [], l2 [] 输出:[]示…

开源模型应用落地-glm模型小试-glm-4-9b-chat-vLLM集成(四)

一、前言 GLM-4是智谱AI团队于2024年1月16日发布的基座大模型,旨在自动理解和规划用户的复杂指令,并能调用网页浏览器。其功能包括数据分析、图表创建、PPT生成等,支持128K的上下文窗口,使其在长文本处理和精度召回方面表现优异&a…

K8S篇(基本介绍)

目录 一、什么是Kubernetes? 二、Kubernetes管理员认证(CKA) 1. 简介 2. 考试难易程度 3. 考试时长 4. 多少分及格 5. 考试费用 三、Kubernetes整体架构 Master Nodes 四、Kubernetes架构及和核心组件 五、Kubernetes各个组件及功…

关于路由笔记

路由 定义: 在计算机网络中,路由是将数据包从源节点传输到目标节点的过程。这个过程涉及到网络中的多个设备,如路由器、交换机等,其中路由器起着关键的决策作用。 工作原理示例: 假设你在一个公司的局域网内&#…

人工智能之人脸识别(人脸采集人脸识别)

文章目录 前言PySimpleGUI 库1-布局和窗口 前言 例如:随着人工智能的不断发展,本文主要介绍关于人工智能中GUI和PyMysql相应用。 本文采用代码+逻辑思路分析的方式有助于理解代码。 PySimpleGUI 库 PySimpleGUI 是一个用于简化 GUI 编程的…

如何找到养生生活视频素材?推荐几个优秀网站

今天,我们来聊一个实用的话题,那就是如何找到优质的养生视频素材。作为自媒体创作者,高质量的视频素材对内容制作至关重要。不论你是刚入行的新手,还是已经积累了一定粉丝的大V,找到合适的养生视频素材都能帮助你更好地…

旋转对称性,旋转矩阵的特征矢量也是T3矩阵的特征矢量

旋转对称性要求T3矩阵,在旋转后,特征矢量没发生改变,特征值大小也没变,即T3矩阵没有改变

美畅物联丨物联网通信新纪元:Cat.1与5G RedCap的差异化应用

​ 在物联网(IoT)迅猛发展的时代,通信标准对物联网设备的连接性、性能和适用性有着极为关键的作用。小编在《美畅物联丨Cat.1与NB-IoT:物联网设备的通信标准对比》中提到Cat.1与NB-IoT的对比区别,后来就有小伙伴问&…