MongoDB数据库 | 三分钟学会MongoDB索引,快来看看与MySQL索引有何不同?

news2024/11/18 23:34:17

在这里插入图片描述
在这里插入图片描述

目录

    • 一、创建索引
      • 1、创建索引
      • 2、通过索引查询
    • 二、复合索引
    • 三、索引内嵌文档
    • 四、索引基数
    • 五、explain
    • 六、为何不使用索引
    • 七、固定集合

一、创建索引

1、创建索引

> db.student.createIndex({"name":1})
{
    "numIndexesBefore" : 1,
    "numIndexesAfter" : 2,
    "createdCollectionAutomatically" : false,
    "ok" : 1
}

2、通过索引查询


> db.student.find({"name":"哪吒"}).explain("executionStats"))
{
        "explainVersion" : "1",
        "queryPlanner" : {
                "namespace" : "test.student",
                "indexFilterSet" : false,
                "parsedQuery" : {
                        "name" : {
                                "$eq" : "哪吒"
                        }
                },
                "maxIndexedOrSolutionsReached" : false,
                "maxIndexedAndSolutionsReached" : false,
                "maxScansToExplodeReached" : false,
                "winningPlan" : {
                        "stage" : "FETCH",
                        "inputStage" : {
                                "stage" : "IXSCAN",
                                "keyPattern" : {
                                        "name" : 1
                                },
                                "indexName" : "name_1",
                                "isMultiKey" : false,
                                "multiKeyPaths" : {
                                        "name" : [ ]
                                },
                                "isUnique" : false,
                                "isSparse" : false,
                                "isPartial" : false,
                                "indexVersion" : 2,
                                "direction" : "forward",
                                "indexBounds" : {
                                        "name" : [
                                                "[\"哪吒\", \"哪吒\"]"
                                        ]
                                }
                        }
                },
                "rejectedPlans" : [ ]
        },
        "executionStats" : {
                "executionSuccess" : true,
                "nReturned" : 0,
                "executionTimeMillis" : 16,
                "totalKeysExamined" : 0,
                "totalDocsExamined" : 0,
                "executionStages" : {
                        "stage" : "FETCH",
                        "nReturned" : 0,
                        "executionTimeMillisEstimate" : 13,
                        "works" : 1,
                        "advanced" : 0,
                        "needTime" : 0,
                        "needYield" : 0,
                        "saveState" : 0,
                        "restoreState" : 0,
                        "isEOF" : 1,
                        "docsExamined" : 0,
                        "alreadyHasObj" : 0,
                        "inputStage" : {
                                "stage" : "IXSCAN",
                                "nReturned" : 0,
                                "executionTimeMillisEstimate" : 13,
                                "works" : 1,
                                "advanced" : 0,
                                "needTime" : 0,
                                "needYield" : 0,
                                "saveState" : 0,
                                "restoreState" : 0,
                                "isEOF" : 1,
                                "keyPattern" : {
                                        "name" : 1
                                },
                                "indexName" : "name_1",
                                "isMultiKey" : false,
                                "multiKeyPaths" : {
                                        "name" : [ ]
                                },
                                "isUnique" : false,
                                "isSparse" : false,
                                "isPartial" : false,
                                "indexVersion" : 2,
                                "direction" : "forward",
                                "indexBounds" : {
                                        "name" : [
                                                "[\"哪吒\", \"哪吒\"]"
                                        ]
                                },
                                "keysExamined" : 0,
                                "seeks" : 1,
                                "dupsTested" : 0,
                                "dupsDropped" : 0
                        }
                }
        },
        "command" : {
                "find" : "student",
                "filter" : {
                        "name" : "哪吒"
                },
                "$db" : "test"
        },
        "serverInfo" : {
                "host" : "DESKTOP-HU0H0AI",
                "port" : 27017,
                "version" : "5.0.14",
                "gitVersion" : "1b3b0073a0b436a8a502b612f24fb2bd572772e5"
        },
        "serverParameters" : {
                "internalQueryFacetBufferSizeBytes" : 104857600,
                "internalQueryFacetMaxOutputDocSizeBytes" : 104857600,
                "internalLookupStageIntermediateDocumentMaxSizeBytes" : 104857600,
                "internalDocumentSourceGroupMaxMemoryBytes" : 104857600,
                "internalQueryMaxBlockingSortMemoryUsageBytes" : 104857600,
                "internalQueryProhibitBlockingMergeOnMongoS" : 0,
                "internalQueryMaxAddToSetBytes" : 104857600,
                "internalDocumentSourceSetWindowFieldsMaxMemoryBytes" : 104857600
        },
        "ok" : 1
}

explain()返回值含义一览:

queryPlanner(查询计划):查询优化选择的计划细节和被拒绝的计划。其可能包括以下值:
queryPlanner.namespace-一个字符串,运行查询的指定命名空间
queryPlanner.indexFilterSet-一个布尔什,表示MongoDB在查询中是否使用索引过滤
queryPlanner.winningPlan-由查询优化选择的计划文档 winningPlan.stage-表示查询阶段的字符串
winningPlan.inputStage-表示子过程的文档 winningPlan.inputStages-表示子过程的文档数组
queryPlanner.rejectedPlans-被查询优化备选并被拒绝的计划数组
executionStats,(执行状态):被选中执行计划和被拒绝执行计划的详细说明:
queryPlanner.nReturned-匹配查询条件的文档数
queryPlanner.executionTimeMillis-计划选择和查询执行所需的总时间(毫秒数)
queryPlanner.totalKeysExamined-扫描的索引总数
queryPlanner.totalDocsExamined-扫描的文档总数
queryPlanner.totalDocsExamined-扫描的文档总数
queryPlanner.executionStages-显示执行成功细节的查询阶段树
executionStages.works-指定查询执行阶段执行的“工作单元”的数量
executionStages.advanced-返回的中间结果数
executionStages.needTime-未将中间结果推进到其父级的工作周期数
executionStages.needYield-存储层要求查询系统产生的锁的次数
executionStages.isEOF-指定执行阶段是否已到达流结束
queryPlanner.allPlansExecution-包含在计划选择阶段期间捕获的部分执行信息,包括选择计划和拒绝计划
serverInfo,(服务器信息):MongoDB实例的相关信息: serverInfo.winningPlan-使用的执行计划
winningPlan.shards-包括每个访问片的queryPlanner和serverInfo的文档数组

索引可以显著缩短查询时间,但是,使用索引也是有代价的,索引字段的增删改操作会花费更长时间,因为在更改数据时,除了更新文档数据,MongoDB还必须更新索引。这个和关系型数据库是一样的。MongoDB的索引机制和关系型数据库的索引机制大同小异。

要选择为哪些字段建索引,可以查看常用的查询以及那些需要快速执行的查询。

二、复合索引

在两个或者多个键上创建索引是必须的,索引会将其所有值按顺序保存,因此按照索引键对文档进行排序的速度要快得多。

> db.student.createIndex({"name":1,"age":1})               ")
{
    "numIndexesBefore" : 2,
    "numIndexesAfter" : 3,
    "createdCollectionAutomatically" : false,
    "ok" : 1
}

符合索引使MongoDB能够高效地执行具有多个子句的查询。当设计基于多个字段的索引时,应该讲用于精确匹配的字段放在最前面,用于范围匹配的字段放在最后面。这样就可以先用第一个索引键进行精确匹配,然后再用第二个索引范围在这个结果集内部进行搜索。

三、索引内嵌文档

MongoDB允许深入文档内部,对内嵌字段和数组创建索引。内嵌对象和数组字段可以和顶级字段一起在符合索引中使用。

可以在内嵌文档的键上创建索引,方法与在普通键上创建索引相同。

在info中的address字段上建立索引。对子文档创建索引,只有进行与子文档字段顺序完全匹配的查询时,查询优化器才能使用"address"上的索引。

> db.teacher.find()                                                                         新园区"}})
{ "_id" : ObjectId("638ca288e96330d24f819182"), "id" : "1", "name" : "哪吒编程", "info" : { "id" : 1, "level" : "1", "address" : "大连市高新园区" } }
{ "_id" : ObjectId("638ca288e96330d24f819183"), "id" : "2", "name" : "云韵", "info" : { "id" : 2, "level" : "1", "address" : "北京市" } }
{ "_id" : ObjectId("638ca288e96330d24f819184"), "id" : "3", "name" : "萧炎", "info" : { "id" : 3, "level" : "2", "address" : "沈阳市青年大街" } }
{ "_id" : ObjectId("638ca289e96330d24f819185"), "id" : "4", "name" : "美杜莎", "info" : { "id" : 4, "level" : "3", "address" : "上海市浦项道" } }
{ "_id" : ObjectId("638ca28ae96330d24f819186"), "id" : "5", "name" : "雅妃", "info" : { "id" : 5, "level" : "2", "address" : "深圳市中山路" } }
> db.teacher.createIndex({"info.address":1})
{
        "numIndexesBefore" : 1,
        "numIndexesAfter" : 2,
        "createdCollectionAutomatically" : false,
        "ok" : 1
}

四、索引基数

基数是指集合中某个字段有多少个不同的值。

通常来说,一个字段的基数越高,这个字段上的索引就越有用。这是因为这样的索引能够迅速将搜索范围缩小到一个比较小的结果集。对于基数比较低的字段,索引通常无法排除大量可能的匹配项。

五、explain

对于慢查询而言,explain 是最重要的诊断工具之一,通过explain可以了解查询都使用了哪些索引以及是如何使用的。对于任何查询,都可以在末尾添加一个explain进行查询分析。

六、为何不使用索引

索引在提取较小的子数据集时是最高效的,而有些查询在不使用索引时会更快。

结果集在原集合中所占的比例越大,索引就会越低效,因为使用索引需要进行两次查找:一次是查找索引项,一次是根据索引的指针区查找其指向的文档。而全表扫描只需进行一次查找:查找文档。在最坏的情况下(返回集合内的所有文档),使用索引进行查找的次数会是全表扫描的两倍,通常会明显比全表扫描慢。

七、固定集合

对于固定大小的集合,当我们向已经满了的固定集合中插入数据时,文档中最旧的文档会被删除,固定集合不允许进行会导致集合大小变化的操作,固定集合中的文档以插入顺序进行存储,并且不需要为已删除文档的空间维护空闲列表。

与MongoDB中的大部分集合不同,固定集合的访问模式是数据被顺序写入磁盘上的固定空间,这让它们在机械硬盘上的写入速度非常快,尤其是当集合拥有专有的磁盘时。

通常来说,对于固定集合,MongoDB优先推荐使用TTL索引,因为它们在WiredTiger存储引擎中性能更好。TTL索引会基于日期类型字段的值和索引的TTL值而过期,并从普通集合中删除数据。

TTL索引允许为每一个文档设置一个超时时间,当一个文档达到其预设的过期时间之后就会被删除。为了防止活跃的会话被删除,可以在会话上有活动发生时,将lastUpdated字段更新为当前时间。
在这里插入图片描述
Java学习路线总结,搬砖工逆袭Java架构师

10万字208道Java经典面试题总结(附答案)

Java基础教程系列

Java高并发编程系列

数据库进阶实战系列

.

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

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

相关文章

【unity3D】Audio Source组件

💗 未来的游戏开发程序媛,现在的努力学习菜鸡 💦本专栏是我关于游戏开发的学习笔记 🈶本篇是unity的Audio Source组件 Audio Source组件常用的属性解释: AudioClip:在这里指定需要播放的音频片段。Output …

Java面试题每日10问(3)

Core Java - OOPs Concepts: static keyword Interview Questions 1.What if the static modifier is removed from the signature of the main method? Program compiles. However, at runtime, It throws an error “NoSuchMethodError.” 2. What is the difference betw…

2023年会发生什么,一点都不会神秘

文/明道云创始人任向晖我很少写市场预测文章,是因为影响经济活动的要素实在太多了。做任何预测的时候,想明白了一二,但没有预计到三,结果可能就完全不一样。过去三年的疫情就是一个典型的例子。但是这个冬天的预测显得格外重要一些…

Redis+注解实现API接口防刷限流

前言 在开发分布式高并发系统时有三把利器来保护系统:缓存、降级、限流。 缓存: 缓存的目的是提升系统访问速度和增大系统处理容量;降级:降级是当服务出现问题或者影响到核心流程时,需要暂时屏蔽掉,待高峰或者问题解…

软件测试之维护性测试

维护性测试用于评估系统能够被预期的维护人员修改的有效性和效率的程度,可从模块化、可重用性、易分析性、易修改性、易测试性、易维护性 1)模块化:评估由独立组件组成的系统或计算机程序,其中一个组件的变更对其他组件的影响大小程度&#x…

【Android 车载 App】实现座椅调节控制十字指针的效果

【Android 车载 App】实现座椅调节控制十字指针的效果效果展示实现方法思路代码第一步,画两条十字虚线第二步,在每个虚线的末端画出圆角三角形第三步,在十字虚线的中间位置画出两个同心圆,一个填充内容,一个描边第四步…

一款新兴的操作pcap的神器

一 前言有机会接触到这款软件,还是同事的一个图,图介绍了开源项目Zed和基于Zed做的一款全流量安全产品Brim。整个产品其实是不少开源项目的一个小集成,只所以感兴趣,除了brim在github有1.5k个star的原因外,更吸引我的是…

缓存的数据一致性

文章目录1.先更新缓存,再更新DB2.先更新DB,再更新缓存3.先删除缓存,后更新DB4.先更新DB,后删除缓存 (推荐)前言: 只要使用到缓存,无论是本地内存做缓存还是使用 redis 做缓存&#…

Neo4j网页服务器端口Cypher操作直接创建知识图谱

案例1:创建新节点、关系 CREATE (n:美国企业家{name:马斯克}) MERGE (n) <-[:主公]- (n1:总统{name:拜登}) RETURN *创建其他节点的时候,可以一次输入:例如 CREATE

代码随想录day32

第32天 前言 终于到周六了&#xff0c;明天可以休息了&#xff0c;哈哈哈 122. 买卖股票的最佳时机 II 题目 给定一个数组&#xff0c;它的第 i 个元素是一支给定股票第 i 天的价格。 设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易&#xff08;多…

DenseNet详解

入门小菜鸟&#xff0c;希望像做笔记记录自己学的东西&#xff0c;也希望能帮助到同样入门的人&#xff0c;更希望大佬们帮忙纠错啦~侵权立删。 ✨完整代码在我的github上&#xff0c;有需要的朋友可以康康✨ https://github.com/tt-s-t/Deep-Learning.git 目录 一、DenseNet网…

深度学习——语言模型(笔记)

语言模型&#xff1a;NLP经典的模型 1.语言模型 ①长度为T的文本序列中词元依次是x1,…,xT&#xff0c;xT被认为是文本序列在时间t处的观测或标签。在给定文本序列&#xff0c;语言模型的目标是估计序列的联合概率p(x1,…,xT) ②序列模型的核心是整个序列文本所出现的概率 应…

国家基础地理信息中心行政边界等矢量数据免费下载保姆级教程--关于地理数据收集与处理的基本工具推荐(7)

关于地理数据收集与处理的基本工具推荐系列&#xff0c;有导航&#xff0c;不迷路&#xff1a; 关于地理数据收集与处理的基本工具推荐(1) —高分辨率卫星影像数据免费下载方式关于地理数据收集与处理的基本工具推荐(2)—10m精度的全球土地覆盖数据下载关于地理数据收集与处理…

勿忘2022,迎接2023

2022真的可以说是很不平凡的一年&#xff0c;很多想做的事情也因为一些原因没有做成。不过2022年已经过去&#xff0c;一年一度的总结还是要来写的。废话不多说&#xff0c;还是定关键词。2017年是“小确幸”和“在路上”&#xff0c;感谢师兄师姐的帮助&#xff0c;接触了很多…

write和fwrite

如果只是普通地以O_RDWR的flag去open一个文件朝里write&#xff08;不考虑创建、扩增&#xff09;&#xff0c;那默认内核会把文件的这个页面读进来缓存在内核里的&#xff0c;也即所谓的page cache。随后再发起新的write syscall写相同的页面时&#xff0c;只要写在page cache…

【博学谷学习记录超强总结,用心分享|产品经理基础总结和感悟13】

这里写目录标题第一章、概述第二章&#xff0c;内容服务产品分析框架&#xff1a;用户-平台-创作者内容服务平台优化思考第一章、概述 在分析文字类内容产品之前&#xff0c;我们先来思考一下内容产品的本质是什么&#xff1f;笔者认为&#xff0c;所有满足用户需求的信息服务…

aws beanstalk 使用docker平台部署beanstalk应用程序

参考资料 使用 Docker 平台分支 之前的文章分享过如何使用eb cli工具创建application和eb环境&#xff0c;本文介绍beanstalk支持的docker容器部署 关于beanstalk环境创建相关的资源和部署逻辑&#xff0c;参考之前的文章《aws beanstalk 使用eb cli配置和启动环境》 $ eb …

指南帮手——协议栈

通过 DNS 获取到 IP 后&#xff0c;就可以把 HTTP 的传输工作交给操作系统中的协议栈。协议栈的内部分为几个部分&#xff0c;分别承担不同的工作。上下关系是有一定的规则的&#xff0c;上面的部分会向下面的部分委托工作&#xff0c;下面的部分收到委托的工作并执行。应用程序…

PyTorch源码编译(windows)

1.打开pytorch源码仓库: https://github.com/pytorch/pytorch#from-source2.PyTorch用途与安装方法:3.Python与编译器版本要求 (Python3.7或者更高,编译器要求支持C17)4.如果要支持CUDA编程,要安装NVIDIA CUDA 11或者更高版本, 安装NVIDIA cuDNN v7或者更高版本注:CUDA不支持Ma…

使用 Flask 快速部署 PyTorch 模型

对于数据科学项目来说&#xff0c;我们一直都很关注模型的训练和表现&#xff0c;但是在实际工作中如何启动和运行我们的模型是模型上线的最后一步也是最重要的工作。 今天我将通过一个简单的案例&#xff1a;部署一个PyTorch图像分类模型&#xff0c;介绍这个最重要的步骤。 …