MongoDB 索引全攻略

news2025/2/8 3:07:25

目录

一、索引介绍

        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.coloradmin.cn/o/1598213.html

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

相关文章

Centos7.6部署minikube

1、什么是minikube ? Minikube是由Kubernetes社区维护的单机版的Kubernetes集群,支持macOS, Linux, and Windows等多种操作系统平台,使用最新的官方stable版本,并支持Kubernetes的大部分功能,从基础的容器编排管理,到…

基于AutoCAD的WMTS服务加载方法与应用研究

"针对在AutoCAD中加载地图存在数据定位操作复杂、数据渲染效率低、无法接入第三方地理信息服务的问题,提出了在AutoCAD中加载OGC标准的网络地图分块服务方法。基于ObjectARX二次开发插件,实现在AutoCAD中加载WMTS服务,兼容了第三方地理信…

基于Springboot的旅游管理系统

基于SpringbootVue的旅游管理系统的设计与实现 开发语言:Java数据库:MySQL技术:SpringbootMybatis工具:IDEA、Maven、Navicat 系统展示 用户登录 首页展示 旅游方案展示 旅游资讯 后台管理员登录 后台管理页面首页 用户管理 …

【自动驾驶】贝叶斯算法在机器学习中的应用研究

目录 第一章:引言 1.1 贝叶斯算法在机器学习中的重要性 1.2 研究背景 1.3 研究目的 1.4 论文结构 第二章:贝叶斯算法概述 2.1 贝叶斯定理 2.2 贝叶斯算法分类 第三章:贝叶斯算法在机器学习中的应用 3.1 贝叶斯分类器 3.2 贝叶斯回…

SpringSecurity源码分析3--UserDetail部分

UserDetailsService.class DaoAuthenticationProvider.class AbstractUserDetailsAuthenticationProvider.class 一个允许子类重写和处理UserDetails对象的基AuthenticationProvider。该类旨在响应UsernamePasswordAuthenticationToken身份验证请求。 AuthenticationProvider…

Gartner 《2024安全和风险管理技术路线图》:高价值技术 DSP 进入广泛部署阶段

近期,Gartner 发布《2024年技术采用路线图:安全与风险管理》(以下简称:《路线图》),该信息图表识别了全球企业正在采用的 44 种与安全相关的技术,并根据采用阶段、部署风险和企业价值进行了映射…

python中的列表、元组、字典、集合(字典篇)

数据类型定义符号访问元素是否可变是否重复是否有序列表 [ ]索引可变可重复有序元组()索引不可变可重复有序字典{key:value}键可变可重复无序集合{ }可变不可重复无序 字典概念 在python语言中,字典属于内置容器类,其…

什么是云安全

云安全和网络安全有所不同,因为云安全一词 比网络安全更涵盖整个企业基础设施。一般来说,当人们提到云安全时,指的是第三方服务提供商提供的 IaaS 云环境。在这种情况下,云安全不仅包括网络安全工具,还包括服务器、容器…

C#基础|数据类型、变量

哈喽,你好啊,我是雷工! 01 数据类型 数据类型是为了方便存储数据的,为了将数据按照不同的分类存储,所以引入数据类型。这个在PLC中已经很熟悉了。 数据类型的作用:就是为了更好地管理内存,为…

[C++][算法基础]求最小生成树(Prim)

给定一个 n 个点 m 条边的无向图,图中可能存在重边和自环,边权可能为负数。 求最小生成树的树边权重之和,如果最小生成树不存在则输出 impossible。 给定一张边带权的无向图 G(V,E),其中 V 表示图中点的集合,E 表示图…

【深度学习】AI修图——DragGAN原理解析

1、前言 上一篇,我们讲述了StyleGAN2。这一篇,我们就来讲一个把StyleGAN2作为基底架构的DragGAN。DragGAN的作用主要是对图片进行编辑,说厉害点,可能和AI修图差不多。这篇论文比较新,发表自2023年 原论文&#xff1a…

拼多多容器文件修改自动上传

拼多多开放平台php环境是官方的linux容器,不能自己搭建ftp上传文件,每每有文件更新都挺麻烦。 有些功能测试不想每次都打包全部代码上去重新发布一次程序生成新的容器,那样太过麻烦和效率低。 一开始搞了一个php的文件管理工具上去&#xf…

高效解决Visual Studio Code中文乱码问题

文章目录 问题解决步骤 问题 Visual Studio Code新建一个文件编码方式总是默认GBK,如果我不修改成默认UTF-8,那么每次运行,如果有中文需要输出就会乱码! 解决步骤 之后我会持续更新,如果喜欢我的文章,请记…

Apache DolphinScheduler 社区 3 月月报

各位热爱 DolphinScheduler 的小伙伴们,DolphinScheduler 社区月报开始更新啦!这里将记录 DolphinScheduler 社区每月的重要更新。 社区为 DolphinScheduler 3.2.x 版本做了诸多功能改进和 bug 修复 DolphinScheduler 月度 Merge Stars 感谢以下小伙伴 …

腾讯云轻量应用服务器端口怎么打开?

腾讯云轻量应用服务器端口怎么打开?在轻量应用服务器控制台的防火墙中开启端口,本文腾讯云百科txybk.com以80端口为例,来详细说下轻量应用服务器端口打开教程,另外可以在腾讯云百科 txy.wiki 查看当前轻量服务器最新的优惠券和配置…

LSTM 循环神经网络原理深度解读与网络结构精细剖析

长短期记忆网络(Long Short-Term Memory, LSTM)是一种特殊的循环神经网络(Recurrent Neural Network, RNN),设计用于解决长期依赖问题,特别是在处理时间序列数据时。 循环神经网络(RNN&#xf…

jenkins(docker)安装及应用

jenkins Jenkins是一个开源的、提供友好操作界面的持续集成(CI)工具,起源于Hudson(Hudson是商用的),主要用于持续、自动的构建/测试软件项目、监控外部任务的运行(这个比较抽象,暂且写上,不做解…

【InternLM】LMDeploy部署实践

1. LMDeploy基本介绍 LMDeploy提供一站式的大模型压缩、部署和服务,其主要特点包括: 高效的推理速度。通过引入持久批处理(即连续批处理)、阻塞 KV 缓存、动态拆分与融合、张量并行、高性能 CUDA 内核等关键特性,提供了比 vLLM 高1.8倍的请…

从零开始写一个RTSP服务器(三)RTP传输H.264

目录 一、RTP封装1.1 RTP数据结构1.2 源码 二、H.264的RTP打包2.1 H.264格式2.2 H.264的RTP打包方式2.3 H.264 RTP包的时间戳计算2.4 源码 三、H.264 RTP打包的sdp描述四、测试 本篇文章目标,使用vlc打开sdp文件后,可以观看到视频数据 一、RTP封装 1.1 …

实战:完美解决md图床问题-nginx图床-2024.4.16(测试成功)

目录 文章目录 目录1、前言图床简介搭建方式需求背景解决方案 2、配置过程1.部署nginx服务2.配置picgo3.配置rsync服务(可选) 3、测试验证关于我最后最后 1、前言 图床简介 对于写博客的朋友们来讲,图床这个东西一定不会陌生,而且在一定程度上也给大家…