MongoDB 索引全攻略

目录

一、索引介绍

        1.1 单字段索引

        1.2 复合索引

        1.3 多键索引

        1.4 主键索引

        1.5 TTL 索引

        1.6 地理空间索引

        1.7 哈希索引

        1.8 创建索引时注意事项

        1.9 索引效果查看

 二、索引实现原理

        2.1 为什么使用 B-Tree

三、执行计划


一、索引介绍

        任何数据库都有索引这一核心功能,索引通常能够极大的提高查询效率,如果没有索引,MongoDB 在读取数据时必须扫描集合中的每个文件,并选取那些符合查询条件的记录。

        这种扫描查询集合的查询方式效率非常低,特别在处理大量数据时。索引是特殊的数据结构,索引存储在一个易于遍历读取的数据集合中,索引是对数据库表中一列或多列的值进行排序的一种结构。

        使用索引通常有如下的作用:

  • 加速查询:通过索引,数据库能够快速定位到符合条件的文档,避免全表扫描,大大减少查询响应时间。
  • 排序优化:索引可用于高效地对查询结果进行排序,无需在内存中对大量数据进行排序操作。
  • 覆盖查询:当索引包含了查询所需的所有字段时,数据库可以直接从索引中获取全部数据,无需访问文档本身,减少了磁盘 I/O。
  • 唯一性约束:创建唯一索引可以确保集合中指定字段的值唯一,防止插入重复数据。

        在 MongoDB 中有很多种索引,下面分别看下不同的索引。

        1.1 单字段索引

        在单个字段上建立的索引,对于单字段索引和排序操作,索引键的排序顺序无关紧要,因为MongoDB 可以在任意方向遍历。

// users 为 collection,创建 username 索引
db.users.createIndex({username: 1})

        

        1.2 复合索引

        多个字段的自定义索引,即复合索引。复合索引中的字段顺序很重要。例如,如果复合索引由{ userid: 1, score: -1} 组成,则索引首先按userid排序,然后在每个userid值内按score排序。在查询时可以按照userid:1,score:-1或者userid:-1,score:1查询,因为这两个顺序和树的组成顺序完全相同,相反执行userid:-1,score:-1将不会使用索引。

        1.3 多键索引

        MongoDB 使用多键索引来索引存储在数组中的内容。如果索引一个包含数组值的字段,MongoDB 会为数组的每个元素创建单独的索引条目。这些多键索引允许查询通过匹配数组的一个或多个元素来选择包含数组的文档。如果索引字段包含数组值,MongoDB 会自动判断是否创建多键索引;你不需要明确指定多键类型。

        1.4 主键索引

        MongoDB 中默认为 _id 字段且不能更改,用于维护聚簇索引树。每个集合都有一个默认的索引:“_id”索引,它是一个特殊的字段,用来唯一标识集合中的每个文档。这个字段通常被用作查询文档的主键,并且MongoDB会自动为其创建一个唯一索引。

        1.5 TTL 索引

        类似于 Redis 的过期时间,为一个字段创建TTL索引后,超时会自动删除整个文档。TTL索引适用于那些具有有效期、需要定期清理过期数据的场景,如会话记录、日志条目、临时消息等。

db.event_log.createIndex({timestamp: 1}, {expireAfterSeconds: 604800})  // 604800秒 = 7天

        1.6 地理空间索引

        特别针对地理空间数据设计的索引,如2dsphere索引用于处理经纬度坐标,支持地理位置查询(如距离计算、边界框查询等)。其他地理空间索引类型包括2d(用于平面坐标)和geoHaystack(已弃用)。

        1.7 哈希索引

        将索引字段的值通过哈希函数计算出哈希值进行索引,适用于等值查询,但不支持范围查询和排序。

        1.8 创建索引时注意事项

        在创建索引时不要过多添加,虽然索引可以有效的提升查询性能,但过多的索引会增加写入成本、占用更多的存储空间,并可能使查询优化器的选择变得复杂。

        创建索引时可能会存在锁表,需要根据具体使用的版本而定。4.2及以上版本在创建索引过程中,仅在索引构建的开始和结束时持有排他锁,构建过程中的其余部分产生交错读取和写入操作。建议在业务低峰期添加索引。

        1.9 索引效果查看

        索引创建后,到底所创建索引的效果如何呢?可以通过一下方式验证,具体就是查看所以的区分度,类似于 MySQL 的 Cardinality。所得的值越接近1说明区分度越高,索引效果越好,

// 索引字段去重后的数量 / 集合的总量
db.collection.distinct("field").length/db.collection.count()

 二、索引实现原理

        MongoDB 是文档型数据库,使用 BSON 格式保存数据,比关系型数据库存储更方便。MySQL 是关系型数据库,数据的关联性非常强,区间访问是常见的一种场景,底层索引组织数据使用B+树,B+树由于数据全部存储在叶子节点,并且通过指针串在一起,这就很容易进行区间遍历甚至全部遍历。

        MongoDB 采用 B-tree 作为其索引的主要数据结构。B-tree 是一种自平衡的多路搜索树。

        自平衡:无论数据如何插入或删除,树的高度始终保持相对稳定,从而保证查询效率接近O(log N),其中N是集合中文档的数量。

        多路分支:每个节点可以有多个子节点,具体数量取决于 B-tree 的阶数。高阶 B-tree 可以更有效地利用磁盘块,减少磁盘 I/O 次数。

        有序存储:B-tree 节点中的键值对按照索引字段的排序规则(升序或降序)排列,便于快速定位和范围查询。

        2.1 为什么使用 B-Tree

        B-Tree 和 B+Tree 都是树形数据结构,用于在数据库中存储和查找数据。它们的主要区别在于数据的存储方式和查找效率。

        B-Tree 的每个节点都包含键和值,所有的键值对都存储在树的内部节点和叶子节点中。这意味着一旦找到了正确的节点,就可以立即获取到对应的值,无需进一步的磁盘 I/O 操作。

        而 B+Tree 只在叶子节点中存储键值对,内部节点只存储键。这意味着查找值时,即使找到了正确的内部节点,还需要进一步查找叶子节点才能获取到值,可能需要额外的磁盘 I/O 操作。

三、执行计划

        MongoDB执行计划(Execution Plan)是描述 MongoDB 如何执行一条查询语句的详细过程和策略,它提供了关于查询优化器如何选择索引、如何访问数据、执行成本估计等方面的详细信息。通过分析执行计划,可以深入了解查询性能、识别潜在的优化点以及调试查询性能问题。

        执行计划语句

db.collection.find({field: value}).explain('verbosity')

        使用 explain()方法附加在查询语句后面来获取执行计划。explain()接受一个可选的verbosity 参数,用来指定返回的执行计划详细程度:    

  • queryPlanner(默认):提供查询计划的基本信息,包括查询类型、候选索引、选定索引及其原因、查询阶段等。
  • executionStats:除了查询计划基本信息外,还包括实际执行时的统计信息,如扫描的文档数、返回的文档数、执行时间、索引使用情况等。
  • allPlansExecution:除了上述信息外,还会实际执行所有候选索引并返回各自的执行统计,有助于对比不同索引的性能。

        执行计划中需要重点关注:COLLSCAN、IXSCAN、keysExamined、docsExamined等关键字。

  • COLLSCAN:代表该查询进行了全表扫描
  • IXSCAN:代表进行了索引扫描
  • keysExamined:代表索引扫描条目
  • docsExamined:代表文档扫描条目

        根据执行计划分析结果,可能要采取不同的优化策略,比如:创建或调整索引、优化查询条件、使用覆盖索引等。

        综上所述,MongoDB 执行计划提供了深入理解查询执行过程和优化查询性能的关键信息。通过解读执行计划的各部分、对比不同计划、分析统计信息,可以针对性地调整索引策略、优化查询语句或调整查询选项,从而提升查询效率。结合使用相关工具和命令,可以实现对查询性能的持续监控和调优。

往期经典推荐:

全面解读MongoDB高可用、高性能与高可扩展架构-CSDN博客

深入剖析MongoDB集群架构设计-CSDN博客

TiDB存储引擎TiKV揭秘-CSDN博客

揭开Spring Bean生命周期的神秘面纱-CSDN博客

决胜微服务架构:OpenFeign轻量级REST客户端的魅力解析_feign配置loadbalancer-CSDN博客

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

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

相关文章

Yolov8项目实践——基于yolov8与OpenCV实现目标物体运动热力图

概述 在数据驱动和定位的世界中,对数据进行解释、可视化和决策的能力变得日益重要。这表明,使用正确的工具和技术可能是项目成功的关键。在计算机视觉领域,存在许多技术来解释从视频(包括录像、流媒体或实时视频)中获…

SpringMVC核心流程解析

SpringMVC核心流程解析 DispatcherServlet的继承关系请求流程分析获取HandlerChain(ControllrtMethod拦截器)获取HandlerAdapter handlerMappings的初始化过程 DispatcherServlet的继承关系 DispatcherServlet本质是一个servlet,既然是servlet,一个请求…

Apache Storm详细配置

Apache Storm是一个分布式实时大数据处理系统,能够并行地对实时数据执行各种操作。它广泛应用于各种需要实时数据处理和分析的场景,例如网站统计、推荐系统、预警系统以及金融系统等。Storm的核心特性包括其简单性、可伸缩性和容错性,它保证了…

Linux 系统中用户、用户组和文件权限管理的常用命令 useradd、usermod、groupadd、groupmod、chmod

🍉 CSDN 叶庭云:https://yetingyun.blog.csdn.net/ 1. useradd useradd 是 Linux 系统中用于创建新用户账户的命令。管理员通常用它来添加新的系统用户,为他们设置初始配置,如主目录、登录 Shell 等。这个命令具有多个选项&#x…

[Algorithm][滑动窗口][水果成篮][最大连续的一个数 Ⅲ][将x减到0的最小操作数]详细讲解

目录 1.水果成篮1.题目链接2.算法原理讲解3.代码讲解 2.找到字符串中所有字母异位词1.题目链接2.算法原理讲解3.代码实现 3.串联所有单词的字串1.题目链接2.算法原理讲解3.代码实现 3.最小覆盖字串1.题目链接2.算法原理讲解 1.水果成篮 1.题目链接 水果成篮 2.算法原理讲解 …

机器学习|决策树|如何计算信息增益|方法总结

如是我闻 :那你说决策树这块还能考点啥呢,也就是算算属性的信息增益(Information Gain)了, 信息增益是一种评估特征(属性)在分类任务中重要性的方法,它基于熵的概念来计算。熵是一个…

notepad++快捷键和宏录制

想要一个删除行的快捷键, 发现没有 有个现成的快捷键 CtrlL : 剪切当前行 , 不是我想要的效果 宏录制很方便,于是就录制一个删除行的宏,设置快捷键为: CtrlD 录制宏: 1, 点击"开始录制" 2, 依次按键: End , Space , Shift Home , Delete , Delete 3, 点击"停止…

Java集合进阶——数据结构

1.栈 模型: 栈模型和一个杯子差不多,一端开口,一端封闭,开口的那端叫栈顶,封闭的那端叫栈底,如图所示 介绍: 元素进入栈中叫进栈/压栈,元素出来叫出栈,元素进栈后会先来…

Appian发布最新版本:通过AI流程自动化推动业务发展

Appian公司于2024年4月16日在弗吉尼亚州麦克莱恩宣布推出Appian平台的最新版本。此版本引入了Process HQ,这是一个集流程挖掘和企业AI于一体的系统,结合了Appian的数据平台。Process HQ为企业运营提供前所未有的可见性,支持数据驱动的决策和流…

CERLAB无人机自主框架: 2-动态目标检测与跟踪

前言:更多更新文章详见我的个人博客主页【MGodmonkeyの世界】 描述:欢迎来到CERLAB无人机自主框架,这是一个用于自主无人飞行器 (UAV) 的多功能模块化框架。该框架包括不同的组件 (模拟器,感知,映射,规划和…

Hadoop——Yarn 调度器和调度算法

Yarn 调度器和调度算法 YARN调度器(Scheduler)是负责将集群资源分配给不同应用程序的组件。它根据应用程序的资源需求和优先级,以及集群的资源供给情况,决定如何分配资源。YARN提供了多种调度器实现,每种调度器都有不…

如何通过MSTSC连接Ubuntu的远程桌面?

正文共:666 字 12 图,预估阅读时间:1 分钟 前面我们介绍了如何通过VNC连接Ubuntu 18.04的远程桌面(Ubuntu 18.04开启远程桌面连接),非常简单。但是有小伙伴咨询如何使用微软的远程桌面连接MSTSC&#xff08…

Go栈内存管理源码解读

基本介绍 栈内存一般是由Go编译器自动分配和释放,其中存储着函数的入参和局部变量,这些参数和变量随着函数调用而创建,当调用结束后也会随之被回收。通常开发者不需要关注内存是分配在堆上还是栈上,这部分由编译器在编译阶段通过…

Android Studio学习笔记——广播机制Broadcast

Android Studio学习笔记——广播机制 5.1 广播机制简介5.2 接收系统广播5.2.1 动态注册监听网络变化5.2.2 静态注册实现开机启动 5.3 发送自定义广播5.3.1 发送标准广播5.3.2 发送有序广播 5.4 使用本地广播5.5 广播的最佳实践——强制下线功能 5.1 广播机制简介 安卓每个应用…

web server apache tomcat11-08-JNDI Resources

前言 整理这个官方翻译的系列,原因是网上大部分的 tomcat 版本比较旧,此版本为 v11 最新的版本。 开源项目 从零手写实现 tomcat minicat 别称【嗅虎】心有猛虎,轻嗅蔷薇。 系列文章 web server apache tomcat11-01-官方文档入门介绍 web…

spring boot后端开发基础

spring boot后端开发基础 Spring Boot一、开发步骤二、Web分析三、跨域问题四、HTTP协议五、Web服务器六、响应前端请求七、springboot常用注解创建一个简单的RESTful API服务层和数据访问层配置类和Bean定义响应体和路径变量 Spring Boot 一、开发步骤 创建项目 添加依赖 项…

k8s部署Eureka集群

部署有状态负载 镜像配置: 环境变量如下: AUTHENTICATE_ENABLEtrue JAVA_OPTS-Dauth.userName账号 -Dauth.password密码 MY_POD_NAMEmetadata.name BOOL_REGISTERtrue BOOL_FETCHtrue APPLICATION_NAME负载名称 EUREKA_INSTANCE_HOSTNAME${MY_POD_NA…

webpack源码分析——enhanced-resolve库之getType、normalize、join和cachedJoin函数

一、PathType 路径类型 const PathType Object.freeze({Empty: 0, // 空Normal: 1, // 默认值Relative: 2, // 相对路径AbsoluteWin: 3, // win 下的绝对路径AbsolutePosix: 4, // posix 下的绝对路径Internal: 5 // enhanced-resolve 内部自定义的一种类型,具体是…

小程序AI智能名片S2B2C商城系统:做内容、造IP、玩社群打造私域流量的新营销秘籍

在数字化浪潮汹涌的新时代,小程序AI智能名片S2B2C商城系统正以其独特的魅力,引领着营销领域的新变革。这套系统不仅将人工智能与小程序技术完美结合,更通过创新的S2B2C模式,为企业打开了一扇通往成功的大门。 面对激烈的市场竞争&…

SQL注入作业

目录 一、万能密码和二阶注入测试 1.万能密码 2.二阶注入测试 二、联合查询注入测试 1.判断注入点 2.判断当前查询语句的列数 3.查询数据库基本信息 4.查询数据库中的数据 三、报错注入 1. 报错注入函数EXTRATVALUE 2.UPDATEXML 四、盲注测试 1.布尔盲注 判断数据…