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.mfbz.cn/a/558915.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

sprinboot+vue集成neo4j图数据库

一 、java后台 1.1 package com.admin.domain;/*** 功能描述:** author wangwei* date 2024-01-15 22:13*/ public class ConnectWeb {private String connectWebId;private String connectWebName;private String connectWebInfo;private String personWebIdAlph…

指针专题(2)

前言 上一节我们学习了指针的相关内容,本节我们继续学习指针专题,更加深入的了解指针,那么废话不多说,我们正式进入今天的学习 1.对数组名的深入理解 在上一节的内容中,我们提到了用指针来访问数组的操作&#xff0c…

昂科烧录器支持Nuvoton新唐科技的低功耗微控制器M482SIDAE

芯片烧录行业领导者-昂科技术近日发布最新的烧录软件更新及新增支持的芯片型号列表,其中Nuvoton新唐科技的低功耗微控制器M482SIDAE已经被昂科的通用烧录平台AP8000所支持。 M482SIDAE以Arm Cortex-M4F为核心,是带有DSP指令集的高效能低功耗微控制器。其…

Mybatis的注解开发

1、概述 mybatis中也提供了注解式开发方式,采用注解可以减少Sql映射文件的配置。 使用注解式开发的话,sql语句是写在java程序中的,这种方式也给sql语句的维护带来成本。 使用注解来映射简单语句会使代码显得更加简洁,但对于稍微…

ASP.NET基于WEB的工作计划流程管理系统的设计与实现

摘 要 信息技术的飞速发展,尤其是网络通讯技术、数据库技术及自动化技术的日新月异,为单位、企业的办公带来了极大的便利。但是由于单位、企业的工作性质众多,工作流程各有差异,企业、单位、部门之间的管理机制各不相同&#xf…

OpenHarmony实战开发-Web自定义长按菜单案例。

介绍 本示例介绍了给Webview页面中可点击元素(超链接/图片)绑定长按/鼠标右击时的自定义菜单的方案。 效果预览图 使用说明 长按Web页面中的图片或者链接元素,弹出自定义的Menu菜单,创建自定义的操作,如复制图片、使…

定时器详解

定时器:Timer类 常用方法方法: 1.schedule(TimeTask timetask,long delay,(long period)): TimeTask:实现了Runnable类,实现时需要重写run方法 delay:表示延迟多少(decay)后开始执行任务,单位是毫秒&#x…

密码学 | 椭圆曲线密码学 ECC 入门(四)

目录 正文 1 曲线方程 2 点的运算 3 求解过程 4 补充:有限域 ⚠️ 知乎:【密码专栏】动手计算双线性对(中) - 知乎 ⚠️ 写在前面:本文属搬运博客,自己留着学习。注意,这篇博客与前三…

LeetCode in Python 200. Number of islands (岛屿数量)

岛屿数量既可以用深度优先搜索也可以用广度优先搜索解决,本文给出两种方法的代码实现。 示例: 图1 岛屿数量输入输出示意图 方法一:广度优先搜索(bfs) 代码: class Solution:def numIslands(self, grid):if not grid:return 0…

【WSL报错】执行:wsl --list --online;错误:0x80072ee7

【WSL报错】执行:wsl --list --online;错误:0x80072ee7 问题情况解决方法详细过程 问题情况 C:\Users\17569>wsl --list --online 错误: 0x80072ee7 解决方法 开系统代理,到外网即可修复!!!!&#x…

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

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

「 网络安全常用术语解读 」软件成分分析SCA详解:从发展背景到技术原理再到业界常用检测工具推荐

软件成分分析(Software Composition Analysis,SCA)是一种用于识别和分析软件内部组件及其关系的技术,旨在帮助开发人员更好地了解和管理其软件的构建过程,同时可帮助安全人员揭秘软件内部结构的神秘面纱。SCA技术的发展…

递归、搜索与回溯算法:回溯,决策树

回溯算法是⼀种经典的递归算法,通常⽤于解决组合问题、排列问题和搜索问题等。 回溯算法的基本思想:从⼀个初始状态开始,按照⼀定的规则向前搜索,当搜索到某个状态⽆法前进时,回退到前⼀个状态,再按照其他…

【计算机组成原理】运算方法和运算器

数据与文字的表示方法 1. 数据格式1.1 定点数表示方法1.1.1 定点小数1.1.2 定点整数 1.2 浮点数表示方法1.2.1 浮点数表示1.2.2 浮点数的规格化1.2.2.1 尾数为原码表示的规格化1.2.2.2 尾数为补码表示的规格化 1.2.3 IEEE754标准⭐ 1.3 十进制数串的表示方法1.3.1 字符串形式1.…

网盘——私聊

在私聊这个功能实现中,具体步骤如下: 1、实现步骤: A、客户端A发送私聊信息请求(发送的信息包括双方的用户名,聊天信息) B、如果双方在线则直接转发给B,不在线则回复私聊失败,对方…

ProgressFlowmon的confluence接口存在任意命令执行漏洞(CVE-2024-2389)

声明: 本文仅用于技术交流,请勿用于非法用途 由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,文章作者不为此承担任何责任。 简介 ProgressFlowmon是一整套用于网络映射、应用程序性能…

客户端动态降级系统

本文字数:4576字 预计阅读时间:20分钟 01 背景 无论是iOS还是Android系统的设备,在线上运行时受硬件、网络环境、代码质量等多方面因素影响,可能会导致性能问题,这一类问题有些在开发阶段是发现不了的。如何在线上始终…

大气的免费wordpress模板

国产的wordpress模板,更适合中国人使用习惯,更符合中国老板的审美的大气wordpress企业官网建站模板。 WordPress模板,也称为主题,是用于定义WordPress网站或博客外观和功能的预设计文件集。这些模板使用HTML、CSS和PHP代码构建&a…

上传文件到HDFS

1.创建文件夹 hdfs -dfs -mkdir -p /opt/mydoc 2.查看创建的文件夹 hdfs -dfs -ls /opt 注意改文件夹是创建在hdfs中的,不是本地,查看本地/opt,并没有该文件夹。 3.上传文件 hdfs dfs -put -f file:///usr/local/testspark.txt hdfs://m…

【深度学习】Vision Transformer

一、Vision Transformer Vision Transformer (ViT)将Transformer应用在了CV领域。在学习它之前,需要了解ResNet、LayerNorm、Multi-Head Self-Attention。 ViT的结构图如下: 如图所示,ViT主要包括Embedding、Encoder、Head三大部分。Class …
最新文章