iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >MongoDB索引概念及使用详解
  • 692
分享到

MongoDB索引概念及使用详解

2024-04-02 19:04:59 692人浏览 薄情痞子
摘要

索引,使用索引可快速访问数据库表中的特定信息。索引是对数据库表中一列或多列的值进行排序的一种结构,例如 employee 表的姓名(name)列。如果要按姓查找特定职员,与必须搜索表中的所有行相比,索引会帮

索引,使用索引可快速访问数据库表中的特定信息。索引是对数据库表中一列或多列的值进行排序的一种结构,例如 employee 表的姓名(name)列。如果要按姓查找特定职员,与必须搜索表中的所有行相比,索引会帮助您更快地获得该信息。


索引的优点:

不需要做全表扫描,只需要扫描索引索引只存储了这个表的数据的一小部分,这小部分可以帮我们实现快速查询,因此扫描的时候只扫描这一小部分即可,如果将这小部分装载入内存中的话,速度会更快

·大大减少了服务器需要扫描的数据量

·索引可以帮助服务器避免排序或使用临时表

·索引可以将随机I/O转换为顺序I/O


索引的缺点:

索引是保存了数据表上的一小部分数据,那么这些数据是需要额外存储的,毫无疑问如果更新了表中的数据,那么响应的索引数据也要跟着更新,加速了查找操作,但是减少了写入速度对查找的加速是否有用还是有待评估的,比如我们将一个表中的按年龄实现了索引创建(在年龄上创建了索引)平时大多数操作都是按照名字上去查找的,那么索引则无任何作用,所谓索引必须跟查找建完全匹配才有意义,但我们要知道大多数的查找未必只在有限字段上执行,也就意味着创建索引必须包含多个段,需要看索引是如何去生成的,对于多个条件可以将索引做为组合索引来查找,所以索引的设计是非常有技巧的

索引本身带来的未必是优势,如果一张表中索引非常的多的话,可能对于整个系统性能的影响是非常大的,如果一张表的本身非常小只有十几行,创建索引反而会减慢速度的,因为全表扫描也未必用不了多长时间

但如果表非常大的话,索引则非常有用,如果数据量过大那么索引反而也未必有意义,比如一张表非常大,上T的数据,可以想象一下创建什么样的索引才可以,所以只能将大表切割成小表,并且分布在不同的物理节点上,对Mysql来说叫做分区;对mongoDB来讲叫shaerd


索引级别:

索引最高级别3星索引

1星:索引国能将相关的记录放置在一起,大大降低了I/O

2星:索引中数据的存储顺序与查找标准中顺序一致(只要设计良好即可)

3星:如果索引中包含查询中所需要的全部数据(覆盖索引)


索引的类别:

·顺序索引
·散列索引

将索引映射至散列桶中,映射是通过散列函数进行的


评估索引标准:

1、访问类型(如果做等值比较 散列比较好,如果做范围查找,那么顺序比较好

2、访问时长(为完成一个访问,基于索引类型访问的时间可能不同)

3、插入时长(更新表的话索引本身可能会有很大代价,如果散列索引的话只不过重新执行以下算法即可,但是对于顺序索引的话,有可能会移动索引列表后面的索引数据)

4、删除时长

5、空间开销


索引类型:

·顺序索引:按照聚集索引存放的文件也被称为索引顺序文件,最常见的索引类型,一般来讲被索引文件记录,如果按照顺序存放则为索引顺序文件,否则为堆文件

·聚集索引:如果某记录文件中的记录顺序是按照对应的搜索码(键/key)的顺序排序的话,被称为主索引

·非聚集索引:搜索码中的指定的次序与记录中的记录次序不一致


根据索引中是否为每个记录响应的创建索引项:

·稠密索引 (每个搜索码值都有一个对应的索引项

·稀疏索引 (并不是每个记录都有索引项)

·多级索引 (索引指向索引,以此类推,最后的索引指向数据;

索引本身,主索引之外的索引被称为辅助索引,而只有主索引才能使用稀疏索引,其他所有必需是稠密索引,而辅助索引必须是稠密索引

·B+树索引:

·Balance Tree 平衡树索引

·每个叶子节点,从叶子至根的距离是相同的,所以叫做平衡树

·层次需要根据数据量来动态创建层次

·B+树是一种顺序索引



散列索引则:

通过散列函数,数据库加载为一次I/O 指针加载数据为2次 I/O。

   I/O是占据时间比例是最大值的,索引散列索引的速度在做精确匹配的时候会更快,因为I/O次数要少的多的多,因此散列索引能够让我们避免访问索引结构的。

散列索引的缺点:散列索引还有可能造成偏斜,长久以来可能发有的散列桶有的满有的空 导致每个节点的负载参差不齐,如果散列函数做的不够随机就有可能造成偏斜的情况

所以散列函数需要做到以下几点:

·分布式随机

·分布式均匀

散列函数适用的场景:精确值匹配,比如做等值比较: = ,IN(), <=> 等


全文索引

默认情况下顺序索引只能索引字段的前有限个字节,假如字段名是test,test是可以创建存储文本量非常大,不可能将所有的数据全部存放在索引中,肯定只在其中抽取部分字节,所以查找标准肯定是最左前缀方式,不能包含整个字段,如果想实现全文匹配关键字匹配的话,这样则只能使用全文索引(mysql中只有myisam引擎支持)(innodb的话则可以借助外界的索引工具来实现比如sphinx)

如果必须要实现全文索引,使用sphinx是个不错的选择


空间索引:

索引中的数据不能查找,必须使用空间索引函数来获取相应查找结果


索引的特性:

·全值匹配:

简单来讲,匹配他的用户名:Name="User12" ,匹配最左前缀:

   Name LIKE"User1%"  

无效: Name LIKE"%User1%"


·匹配列前缀:与最左前缀一样(Name LIKE"User1%"  无效: Name LIKE"%User1%") 假如组合索引创建了2个字段:Name,Age 从最左侧开始则有效,那么Age > 80 这样则没有任何意义,因为查找条件一定必须从最左边开始的,但是反过来则非常用有:(Age,Name)

匹配范围值:精确匹配某一列并范围匹配另外一列 比如name=12并age大于80


只访问索引的查询:

假设顺序索引是3级,要找到对应的行数据,如果没有使用覆盖索引,那么需要几次I/O:首先查找到根索引. 然后查找下一级索引,如果下一级索引在磁盘上,那么意味着将装载数据块,这为1次io ,再一次索引则又消耗一次IO,再次装载硬盘数据,则又一次I/O,如果事先根索引没有被加载,那么至少需要4次I/O才会找到数据

主键,唯一键 都是顺序索引,但是唯一不同的地方是:主键是不能重复 不能为空,唯一键可以重复可以为空


创建索引

> db.testcoll.find()

{ "_id" : ObjectId("531fbe8d020f14309ee1410a"), "Name" : "User1","Age" : 1, "Gender" : "M", "preferbook": [  "blue book",  "yellow book" ] }
{ "_id" : ObjectId("531fbe8d020f14309ee1410b"), "Name" : "User2","Age" : 2, "Gender" : "M", "preferbook": [  "blue book",  "yellow book" ] }
{ "_id" : ObjectId("531fbe8d020f14309ee1410c"), "Name" : "User3","Age" : 3, "Gender" : "M", "preferbook": [  "blue book",  "yellow book" ] }

如上所示,我们要在用户字段名上创建索引,注意的是字段id默认就是索引,而且是主键索引,我们在主键索引之外创建索引都被称为辅助索引 ,因为表内大多数都是根据用户名来查找的,所以希望根据用户名来查找索引:


使用命令ensureIndex 在Name字段上创建索引

> db.testcoll.ensureIndex({Name:1})

查看索引:

> db.testcoll.getIndexes()
[
    {
         "v" : 1,
         "key" : {
             "_id" : 1
         },
         "ns" :"testdb.testcoll",
         "name" :"_id_"
    },

#第二个索引是在name上创建,是我们自己指定的,如下所示:

    {
         "v" : 1,
         "key" : {
             "Name" : 1
         },
         "ns" :"testdb.testcoll",
         "name" :"Name_1"
    }

删除索引:

可以使用dropIndex 将name字段的索引删除

> db.testcoll.dropIndex({Name:1})
{ "nIndexesWas" : 2, "ok" : 1 }

再次查看其索引

> db.testcoll.getIndexes()
[
    {
         "v" : 1,
         "key" : {
             "_id" : 1
         },
         "ns" :"testdb.testcoll",
         "name" :"_id_"
    }
]

删除coll所有的索引

> db.testcoll.dropIndex({Name:1})


同时也支持使用唯一索引,我们可以在name这个字段上创建唯一索引,也就意味着用户名不得出现重复的名字

#唯一索引

> db.testcoll.ensureIndex({Name:1},{unique:true})

#稀疏索引

> db.testcoll.ensureIndex({Name:1},{sparse:true})


MongoDB中所支持的索引类型

对monGodb来讲,索引可以创建在collection级别,也可以创建在sub-field中()子collection

完全可以根据自己的需求创建,那么索引可以将随机IO转换为顺序IO

索引类型:

1、单键索引(创建在一个字段上的索引)

2、组合索引(上面提到了)

3、多键索引(一个文档中某个字段的值可以是数组,如果创建在这么个字段上,一个字段上有多个值,则为多键索引,(一个值为一个数组))

4、空间索引(只能使用空间索引函数,与mysql一致)

5、文本索引(全文索引)

6、哈希索引


创建哈希索引的话,必须明确说明哈希的格式才可以,如下所示:

    >db.testcoll.ensureIndex({Name:"hashed"})

    > db.testcoll.dropIndex({Name:"hashed"})


显示索引是否能用到:

显示查询语句是否能真正用到所创建的索引:

> db.testcoll.find({Name: "User19"}).explain()
{
    "cursor" : "BtreeCursor Name_1",
    "isMultiKey" : false,                    #是否用到键
    "n" : 1,
    "nscannedObjects" : 1,
    "nscanned" : 1,                       #扫描了多少个记录
    "nscannedObjectsAllPlans" : 1,
    "nscannedAllPlans" : 1,
    "scanAndOrder" : false,                #扫描后有没有记录
    "indexOnly" : false,                   #是否用到索引,是否仅在索引中
    "nYields" : 0,
    "nChunkSkips" : 0,
    "millis" : 0,
    "indexBounds" : {
         "Name" : [
             [
                  "User19",
                  "User19"
             ]
         ]
    },
    "server" : "localhost:27017"
}


将索引删除:

> db.testcoll.find({Name: "User19"}).explain()
{
    "cursor" : "BasicCursor",
    "isMultiKey" : false,
    "n" : 1,
    "nscannedObjects" : 99,             #扫描的对象为全部,意为全表扫描
    "nscanned" : 99,
    "nscannedObjectsAllPlans" : 99,
    "nscannedAllPlans" : 99,
    "scanAndOrder" : false,
    "indexOnly" : false,
    "nYields" : 0,
    "nChunkSkips" : 0,
    "millis" : 0,
    "indexBounds" : {

    },
    "server" : "localhost:27017"
}

在查询的时候可以用hint指定使用的索引

> db.testcoll.find({Name: "User19"}).hint({Name:1}).explain()


创建组合索引

> db.testcoll.ensureIndex({Name:1,Age:1},{uniqe:true})

> db.testcoll.getIndexes()
[
    {
         "v" : 1,
         "key" : {
             "_id" : 1
         },
         "ns" :"testdb.testcoll",
         "name" :"_id_"
    },
    {
         "v" : 1,
         "key" : {
             "Name" : 1,
             "Age" : 1
         },
         "ns" :"testdb.testcoll",
         "name" :"Name_1_Age_1",
         "uniqe" : true
    }
]

如果不指定则在name:1上查找索引。如下所示:

> db.testcoll.find({Name: "User19"}).explain()
{
    "cursor" : "BtreeCursor Name_1_Age_1",
    "isMultiKey" : false,
    "n" : 1,
    "nscannedObjects" : 1,
    "nscanned" : 1,
    "nscannedObjectsAllPlans" : 1,
    "nscannedAllPlans" : 1,
    "scanAndOrder" : false,
    "indexOnly" : false,
    "nYields" : 0,
    "nChunkSkips" : 0,
    "millis" : 0,
    "indexBounds" : {
         "Name" : [
             [
                  "User19",
                  "User19"
             ]
         ],
         "Age" : [
             [
                  {
                       "$minElement" : 1
                  },
                  {
                       "$maxElement" : 1
                  }
             ]
         ]
    },
    "server" : "localhost:27017"
}



您可能感兴趣的文档:

--结束END--

本文标题: MongoDB索引概念及使用详解

本文链接: https://www.lsjlt.com/news/37270.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • MySQL约束与索引概念详解
    目录一、关系型数据库设计规则二、数据完整性和约束与索引的概念三、约束的应用一、关系型数据库设计规则 遵循ER模型和三范式 E entity 代表实体的意思 对应到数据库当中的一张表R relationship 代表关系的...
    99+
    2023-04-07
    MySQL约束与索引 MySQL约束 MySQL索引
  • Oracle索引的概念及分类是什么
    这期内容当中小编将会给大家带来有关Oracle索引的概念及分类是什么,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。一.索引介绍 1.1 索引的创建语法...
    99+
    2024-04-02
  • C++详细分析讲解引用的概念与使用
    目录1.引用的概念2.引用的格式3.引用的特性4.取别名原则5.引用的使用场景做参数做返回值int&Count()的讲解传值传引用效率比较6.引用和指针的不同点1.引用的概念...
    99+
    2024-04-02
  • MongoDB索引机制详解
    目录⭐ MongoDB 的索引机制⭐ 索引的类型 创建索引 - 单字段索引 创建索引 - 多字段索引 创建索引 - 唯一性索引 创建索引 - 文本索引 创建索引 - 地理空间索引⭐ 查看所有索引⭐ 删除索引⭐ Mongo...
    99+
    2023-04-23
    MongoDB的索引机制 MongoDB的索引 Python MongoDB
  • gRPC实践之proto及Maven插件概念及使用详解
    目录一. 前言二. proto 的概念和使用2.1 具体的执行流程三. 生成Java文件的核心类3.1 grpc 类其他 stub 对象3.2 DTO 和 Build 类总结一. 前...
    99+
    2023-05-16
    gRPC proto Maven插件 gRPC 插件概念
  • AJAX概念以及使用
    AJAX (Asynchronous JavaScript and XML) 是一种用于在网页上实现异步数据交互的技术。它允许网页在...
    99+
    2023-09-23
    AJAX
  • mysql索引基数概念与用法示例
    本文实例讲述了mysql索引基数概念与用法。分享给大家供大家参考,具体如下: Cardinality(索引基数)是mysql索引很重要的一个概念 索引基数是数据列所包含的不同值的数量。例如,某个数据列包含值...
    99+
    2024-04-02
  • MongoDB TTL索引的实例详解
    MongoDB TTL索引的实例详解 TTL索引是一种特殊类型的单字段索引,主要用于当满足某个特定时间之后自动删除相应的文档。也就是说集合中的文档有一定的有效期,超过有效期的文档就会失效,会被移除。也即是数...
    99+
    2024-04-02
  • MySQL索引详解:了解unique索引的作用及用法
    MySQL索引详解:了解unique索引的作用及用法 在数据库中,索引是一种数据结构,它可以加快数据的检索速度。在MySQL中,索引是一种很重要的数据结构,它可以帮助我们更高效地检索数...
    99+
    2024-04-02
  • 关于Eureka的概念作用以及用法详解
    目录一、概念1.1、什么是服务治理1.2、 什么是Eureka1.3、 Eureka包含两个组件1.4、 什么场景使用Eureka1.5、 Eureka停更1.6、代码要实现的内容二...
    99+
    2023-05-20
    Eureka概念 Eureka作用 Eureka用法
  • vue使用websocket概念及示例
    目录概念部分:使用示例概念部分: 1,WebSocket 是 HTML5 提供的 TCP 连接上进行全双工通讯的协议。一次握手之后,服务器和客户端可以互相主动通信,双向传输数据。 2...
    99+
    2024-04-02
  • K8s-helm简介及基本概念详解
    目录Helm简介一、什么是 Helm(官网:https://helm.sh/)二、Helm中的基本概念Chart三、从Helm2到Helm3的变化四、Helm版本支持策略Helm简介...
    99+
    2024-04-02
  • java中IO的概念及使用
    本篇内容主要讲解“java中IO的概念及使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“java中IO的概念及使用”吧!目录一.认识IOIO的分类IO的方式IO读写的方式IO的特性二.文件操作...
    99+
    2023-06-20
  • JSON Schema概念及使用场景
    目录1.什么是JSON Schema2. JSON Schema的应用场景2.1 表单数据校验2.2 接口数据校验2.3 低代码 low-code1.什么是JSON Schema 相...
    99+
    2024-04-02
  • Iptables防火墙四表五链概念及使用技巧详解
    目录1.链的概念2.Iptables五种链的概念3.Iptables数据流向经过的表4.Iptables防火墙四种表的概念5.Iptables防火墙表与链之间的优先级概念6.Ipta...
    99+
    2022-11-13
    Iptables防火墙四表五链 Iptables防火墙
  • PHP值解析:详解PHP中值的概念及应用
    PHP值解析:详解PHP中值的概念及应用 在PHP编程中,值是一个非常基础且重要的概念。在本文中,我们将深入探讨PHP中值的概念及其在实际编程中的应用。我们将从基本值类型,变量,数组,...
    99+
    2024-04-02
  • mysql 索引使用及优化详情
    目录前言mysql索引原理mysql索引分类索引创建语法1、创建索引2、查看索引3、删除索引4、为 username和password创建联合索引5、给user表添加一个info的字...
    99+
    2024-04-02
  • C++BloomFilter布隆过滤器应用及概念详解
    目录一、布隆过滤器概念二、布隆过滤器应用三、布隆过滤器实现1.插入2.查找3.删除四、布隆过滤器优缺五、结语一、布隆过滤器概念 布隆过滤器是由布隆(Burton Howard Blo...
    99+
    2023-03-08
    C++ BloomFilter布隆过滤器 C++ BloomFilter C++布隆过滤器
  • Java中关于二叉树的概念以及搜索二叉树详解
    目录一、二叉树的概念为什么要使用二叉树?树是什么?树的相关术语!根节点路径父节点子节点叶节点子树访问层(深度)关键字满二叉树完全二叉树二叉树的五大性质二、搜索二叉树插入删除hello...
    99+
    2024-04-02
  • 详解C#中委托的概念与使用
    目录委托的概念多播委托拖动按钮委托的概念 委托这个名字取的神乎其神的,但实质是函数式编程,把函数作为参数传递给另一个参数。对于C语言程序员来说,就是把函数指针当作参数传递给另一个函数...
    99+
    2023-02-27
    C#委托使用 C#委托
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作