首页 > 数据库 >MongoDB基础之索引分析

MongoDB基础之索引分析

时间:2022-11-05 19:12:43浏览次数:47  
标签:分析 MongoDB db 查询 索引 创建 createIndex

目录

1 索引

1.1 定义

索引通常能够极大的提高查询的效率,如果没有索引,MongoDB在读取数据时必须扫描集合中的每个文件并选取那些符合查询条件的记录。
这种扫描全集合的查询效率是非常低的,特别在处理大量的数据时,查询可以要花费几十秒甚至几分钟,这对网站的性能是非常致命的。

索引是特殊的数据结构,索引存储在一个易于遍历读取的数据集合中,索引是对数据库表中一列或多列的值进行排序的一种结构

由于索引存在于RAM中,所以覆盖索引 从索引中获取数据比通过扫描文档读取数据要快得多

MongoDB中索引大部分是排序的,排序索引意义:

  • MongoDB中,排序操作,可以通过从索引中按照索引的顺序获取文档的方式,来保证结果的有序性。
  • 如果MongoDB的查询计划器(planner)没法从索引中得到排序顺序,那么它就需要在内存中对结果排序,相比于不用索引的排序操作,用索引会有更好的性能。
  • 关键不用索引的排序操作,会在用了超过32MB内存时终止,也就是说MongoDB只能支持32MB的非索引排序

1.2 创建索引

MongoDB使用 createIndex() 方法来创建索引
注意:在 3.0.0 版本前创建索引方法为 db.collection.ensureIndex(),之后的版本使用了 db.collection.createIndex() 方法,ensureIndex() 还能用,但只是 createIndex() 的别名。

createIndex()方法基本语法格式如下所示:

db.collection.createIndex(keys, options)

语法中 Key 值为要创建的索引字段,1 为指定按升序创建索引,如果想按降序来创建索引指定为 -1 即可
createIndex() 接收可选参数,可选参数列表如下:

Parameter Type Description
background Boolean 建索引过程会阻塞其它数据库操作,background可指定以后台方式创建索引,即增加 "background" 可选参数。 "background" 默认值为false。
unique Boolean 建立的索引是否唯一。指定为true创建唯一索引。默认值为false.
name string 索引的名称。如果未指定,MongoDB的通过连接索引的字段名和排序顺序生成一个索引名称。
dropDups Boolean 3.0+版本已废弃。在建立唯一索引时是否删除重复记录,指定 true 创建唯一索引。默认值为 false.
sparse Boolean 对文档中不存在的字段数据不启用索引;这个参数需要特别注意,如果设置为true的话,在索引字段中不会查询出不包含对应字段的文档.。默认值为 false.
expireAfterSeconds integer 指定一个以秒为单位的数值,完成 TTL设定,设定集合的生存时间。
v index version 索引的版本号。默认的索引版本取决于mongod创建索引时运行的版本。
weights document 索引权重值,数值在 1 到 99,999 之间,表示该索引相对于其他索引字段的得分权重。
default_language string 对于文本索引,该参数决定了停用词及词干和词器的规则的列表。 默认为英语
language_override string 对于文本索引,该参数指定了包含在文档中的字段名,语言覆盖默认的language,默认值为 language.
创建索引指定升序
db.col.createIndex({"title":1})

createIndex() 方法中也可以设置使用多个字段创建索引(关系型数据库中称作复合索引)
>db.col.createIndex({"title":1,"description":-1})

在后台创建索引
db.values.createIndex({open: 1, close: 1}, {background: true})
通过在创建索引时加 background:true 的选项,让创建工作在后台执行

1.3 查看删除索引

查看集合索引
db.col.getIndexes()

查看集合索引大小
db.col.totalIndexSize()

删除集合所有索引
db.col.dropIndexes()

删除集合指定索引
db.col.dropIndex("索引名称")

1.4 查询分析

MongoDB 查询分析可以确保我们所建立的索引是否有效,是查询语句性能分析的重要工具。
MongoDB 查询分析常用函数有:explain()hint()

创建索引
db.test.createIndex({'title':1});

查询分析
db.test.find({'title':1}).explain();

分析结果:

// 1
{
    "explainVersion": "1",
    "queryPlanner": {
        "namespace": "mydb.test",
        "indexFilterSet": false,
        "parsedQuery": {
            "title": {
                "$eq": 1
            }
        },
        "queryHash": "6E0D6672",
        "planCacheKey": "1953B8BB",
        "maxIndexedOrSolutionsReached": false,
        "maxIndexedAndSolutionsReached": false,
        "maxScansToExplodeReached": false,
        "winningPlan": {
            "stage": "FETCH",
            "inputStage": {
                "stage": "IXSCAN",
                "keyPattern": {
                    "title": 1
                },
                "indexName": "title_1",
                "isMultiKey": false,
                "multiKeyPaths": {
                    "title": [ ]
                },
                "isUnique": false,
                "isSparse": false,
                "isPartial": false,
                "indexVersion": NumberInt("2"),
                "direction": "forward",
                "indexBounds": {
                    "title": [
                        "[1.0, 1.0]"
                    ]
                }
            }
        },
        "rejectedPlans": [ ]
    },
    "command": {
        "find": "test",
        "filter": {
            "title": 1
        },
        "$db": "mydb"
    },
   
 
    "ok": 1
}

1.4.1 索引分析 explain

explain操作提供了查询信息,使用索引及查询统计等。有利于我们对索引的优化。
接下来我们在 users 集合中创建 genderuser_name 的索引:

>db.users.createIndex({gender:1,user_name:1})

现在在查询语句中使用 explain :

>db.users.find({gender:"M"},{user_name:1,_id:0}).explain()

1.4.2 强制使用索引 hint

虽然MongoDB查询优化器一般工作的很不错,但是也可以使用 hint来强制 MongoDB 使用一个指定的索引。
这种方法某些情形下会提升性能。 一个有索引的 collection并且执行一个多字段的查询

如下查询实例指定了使用 gender 和 user_name 索引字段来查询:

>db.users.find({gender:"M"},{user_name:1,_id:0}).hint({gender:1,user_name:1})

可以使用 explain() 函数来分析以上查询:

>db.users.find({gender:"M"},{user_name:1,_id:0}).hint({gender:1,user_name:1}).explain()

1.5 嵌套索引

示例文档如下:

{
   "address": {
      "city": "Los Angeles",
      "state": "California",
      "pin": "123"
   },
   "tags": [
      "music",
      "cricket",
      "blogs"
   ],
   "name": "Tom Benzamin"
}

1.5.1 索引数组字段

假设我们基于标签来检索用户,为此我们需要对集合中的数组 tags 建立索引。
在数组中创建索引,需要对数组中的每个字段依次建立索引。所以在我们为数组 tags 创建索引时,会为 music、cricket、blogs三个值建立单独的索引。

使用以下命令创建数组索引:

>db.users.createIndex({"tags":1})

创建索引后,为了验证我们使用使用了索引,可以使用 explain 命令:

>db.users.find({tags:"cricket"}).explain()

1.5.2 索引子文档字段

假设我们需要通过city、state、pincode字段来检索文档,由于这些字段是子文档的字段,所以我们需要对子文档建立索引。

为子文档的三个字段创建索引,命令如下:

>db.users.createIndex({"address.city":1,"address.state":1,"address.pincode":1})

1.6 全文索引

示例文档:

{
   "post_text": "enjoy the mongodb articles on test",
   "tags": [
      "mongodb",
      "test"
   ]
}

创建索引:

db.posts.ensureIndex({post_text:"text"})

使用全文索引
现在我们已经对 post_text 建立了全文索引,我们可以搜索文章中的关键词 test:

>db.posts.find({$text:{$search:"test"}})

删除全文索引
删除已存在的全文索引,可以使用 find 命令查找索引名:

>db.posts.getIndexes()

通过以上命令获取索引名,本例的索引名为post_text_text,执行以下命令来删除索引:

db.posts.dropIndex("post_text_text")

1.7 索引限制

  • 额外开销
    每个索引占据一定的存储空间,在进行插入,更新和删除操作时也需要对索引进行操作。所以,如果很少对集合进行读取操作,建议不使用索引。
  • 内存(RAM)使用
    由于索引是存储在内存(RAM)中,应该确保该索引的大小不超过内存的限制。
    如果索引的大小大于内存的限制,MongoDB会删除一些索引,这将导致性能下降。
  • 索引键限制
    从2.6版本开始,如果现有的索引字段的值超过索引键的限制,MongoDB中不会创建索引。
  • 插入文档超过索引键限制
    如果文档的索引字段值超过了索引键的限制,MongoDB不会将任何文档转换成索引的集合。与mongorestore和mongoimport工具类似。
  • 最大范围
    集合中索引不能超过64
    索引名的长度不能超过128个字符
    一个复合索引最多可以有31个字段
  • 查询限制
    索引不能被以下的查询使用:
    • 正则表达式及非操作符,如 $nin, $not, 等。
    • 算术运算符,如 $mod, 等。
    • $where 子句

标签:分析,MongoDB,db,查询,索引,创建,createIndex
From: https://www.cnblogs.com/jingzh/p/16860864.html

相关文章

  • cesium源码分析-Worker&gltf
    Worker:cesium中使用线程的一个方面是进行几何数据计算,通常计算耗时,放到线程中计算也很合理,但是通常几何数据占用相当大的内存,虽然浏览器中主线程与子线程传递数据可以使用......
  • 【分布式技术专题】「架构实践于案例分析」盘点高并发场景的技术设计方案和规划
    自知之明是最难得的知识。高并发是什么?⾼并发(HighConcurrency)是互联⽹分布式系统架构设计中必须考虑的因素之⼀,它通常是指通过设计保证系统能够同时并⾏处理很多请求。高并......
  • 虚拟货币——比特币行情价格分析
    最近挖以太币的朋友们在关注以太坊行情时,一定会发现以太币的价格对比之前上涨了不少。肯定有部分朋友想了解这次上涨的原因,我们特地为此查询了一番。因为比特币相当于虚拟......
  • MySQL高级3【性能分析工具-索引优化-查询优化】尚硅谷
    第09章性能分析工具的使用1.数据库服务器的优化步骤当我们遇到数据库调优问题的时候,该如何思考呢?这里把思考的流程整理成下面这张图。整个流程划分成了观察(Showstat......
  • mongodb 导出操作
    我的是备份数据库,链接到数据库服务器来备份的终端shell命令实现远程连接服务器:mongo-host10.202.***.**-port27017--authenticationDatabasexz**导出远程服......
  • 基于国产芯片RK1126的智能视频分析网关
    产品简介智能边缘计算网关力求打造一个开放式、可扩展、二次开发升级的智能型AI终端,硬件基于arm的CPU,2T算力的NPU,具备更低的功耗,更高的性能,同时扩展多路外围接口,如RS232、4......
  • Spring Data MongoDB--MongoTemplate查询数据--方法/实例
    简介说明        本文用示例介绍SpringDataMongoDB(MongoTemplate)查询数据的方法。查询方法分类mongoTemplate.find //返回listmongoTemplate.findOne //返回1......
  • 【lwip】09-IPv4协议&超全源码实现分析
    目录前言9.1IP协议简述9.2IP地址分类9.2.1私有地址9.2.2受限广播地址9.2.3直接广播地址9.2.4多播地址9.2.5环回地址9.2.6本地链路地址9.2.7本网络本主机地址9.2.8......
  • PageHelper源码分析
    PageHelper源码分析分析版本:5.2.0项目地址:https://github.com/pagehelper/Mybatis-PageHelper可以看下作者写的关于拦截器的文章。分页的原理,就是根据Mybatis提供的......
  • ysoserial CommonsColletions6分析
    前言CommonsCollectionsGadgetChainsCommonsCollectionVersionJDKVersionNoteCommonsCollections1CommonsCollections3.1-3.2.11.7(8u71之后已修复不......