MongoDB 索引的使用

本文涉及的产品
云数据库 MongoDB,通用型 2核4GB
简介: MongoDB 索引的使用

1 索引概述

索引支持在 MongoDB 中高效地执行查询,避免 MongoDB 执行全集合扫描来选择与查询语句匹配的文档,这种扫描全集合的查询效率是非常低的,特别在处理大量的数据时,查询要花费几十秒甚至几分钟,严重影响网站的整体性能。如果查询存在适当的索引,MongoDB 可以使用该索引限制必须检查的文档数。

索引是特殊的数据结构,以易于遍历的形式存储集合数据集的一小部分,索引存储特定字段或一组字段的值,按字段值排序,索引项的排序支持有效的相等匹配和基于范围的查询操作,MongoDB 可以使用索引中的排序返回排序结果,MongoDB 索引使用 B 树数据结构。

2. 索引的类型

2.1 单字段索引

MongoDB 支持在文档的单个字段上创建自定义的升序/降序索引,称为单字段索引。对于单个字段索引和排序操作,索引键的排序顺序并不重要,因为 MongoDB 可以在任何方向上遍历索引。

2e718f6de6d94987ae2f2182c528d9c8.png

2.2 复合索引

MongoDB 还支持多个字段的用户定义索引,即复合索引。复合索引中列出的字段顺序具有重要意义,例如,如果复合索引由{userid:1,score:-1} 组成,则索引首先按userid 正序排序,然后在每个userid的值内,再按 score 倒序排序。

2e718f6de6d94987ae2f2182c528d9c8.png

2.3 其他索引

(1) 地理空间索引:为了支持对地理空间坐标数据的有效查询,MongoDB 提供了两种特殊的索引,返回结果时使用平面几何的二维和返回结果时使用球面几何的三维球面索引。

(2) 文本索引:MongoDB 提供了一种文本索引类型,支持在集合中搜索字符串内容,这些文本索引不存储特定于语言的停止词,而将集合的词作为词干,只存储词根。


(3) 哈希索引:为了支持基于散列的分片,MongoDB 提供了散列索引类型,它对字段值的散列进行索引,这些索引在其范围内的值分布更加随机,但只支持相等匹配,不支持基于范围的查询。

3. 索引的管理操作

3.1 查看索引

语法格式如下:

db.collection.getIndexes()

例如,查看 comment 集合中所有的索引情况:2e718f6de6d94987ae2f2182c528d9c8.png

查询结果中显示的是 _id 索引,MongoDB 在创建集合的过程中,在 _id 字段上自动创建一个唯一的索引,默认为 _id,该索引可以防止客户端插入两个具有相同值的文档,不能在_id字段上删除索引

3.2 创建索引

语法格式如下:

db.collection.createIndex(keys,options)

参数:

Parameter Type Description
keys document 包含字段和值对的文档,其中字段是索引键,值描述该字段的索引类型,对于字段上的升序索引,指定值为1,对于降序索引,指定值为-1. 例如, {字段:1或-1}
options document 可选,包含一组控制索引的创建的选项的文档

options 列表:

Parameter Type Description
background boolean 建索引过程会阻塞其他数据库操作,background 可指定以后台方式创建索引,增加 background 可选参数,默认值为 false
unique boolean 建立的索引是否唯一,指定为 true 创建唯一索引,默认值为 false
name string 索引的名称,如果未指定,MongoDB 通过连接索引的字段名称和排序顺序生成一个索引名称
sparse boolean 对文档中不存在的字段数据不启用索引,默认值为 false,如果设置为 true 的话,在索引字段中不会查询查询出不包含对应字段的文档
expireAfterSeconds integer 指定一个以秒为单位的数值,完成 TTL 设定,设定集合的生存时间
v index version 索引的版本号,默认的索引版本取决于 mongodb 创建索引时运行的版本
weights document 索引权重值,数值在1到99,999之间,表示该索引相对于其他索引字段的得分权重
default_language string 对于文本索引,该参数决定了停用词及词干和词器的规则的列表,默认为英语
language_override string 对于文本索引,该参数指定了包含在文档中的字段名,语言覆盖默认值为 language

(1) 单字段索引,对 userid 字段建立升序索引:

db.comment.createIndex({userid:1})

2e718f6de6d94987ae2f2182c528d9c8.png

(2) 复合索引,对 useridnickname 两个字段建立复合索引:

db.comment.createIndex({userid:1, nickname:-1})
• 1

2e718f6de6d94987ae2f2182c528d9c8.png

3.3 删除索引

语法格式如下:

db.collection.dropIndex(index)
• 1

参数:

Parameter Type Description
index string or document 指定要删除的索引,可以通过索引名称或索引规范文档指定索引,如果删除文本索引,需要指定索引名称

例如,删除 comment 集合中 userid 字段的升序索引:

db.comment.dropIndex({userid:1})

2e718f6de6d94987ae2f2182c528d9c8.png

如果需要一次性删除所有索引,语法格式如下:

db.collection.dropIndexes()

例如,删除 comment 集合中的所有索引(除 _id 索引外):

db.comment.dropIndexes()

2e718f6de6d94987ae2f2182c528d9c8.png

4. 索引的使用

4.1 执行计划

分析查询性能通常使用执行计划来查看查询的情况,如查询耗费的时间、是否基于索引查询等。

语法格式如下:

db.collection.find(query,options).explain(options)

查看根据 userid 查询数据的情况:

>db.comment.find({userid:"1003"}).explain()
{ queryPlanner: 
   { plannerVersion: 1,
     namespace: 'article.comment',
     indexFilterSet: false,
     parsedQuery: { userid: { '$eq': '1003' } },
     winningPlan: 
      { stage: 'FETCH',
        inputStage: 
         { stage: 'IXSCAN',
           keyPattern: { userid: 1 },
           indexName: 'userid_1',
           isMultiKey: false,
           multiKeyPaths: { userid: [] },
           isUnique: false,
           isSparse: false,
           isPartial: false,
           indexVersion: 2,
           direction: 'forward',
           indexBounds: { userid: [ '["1003", "1003"]' ] } } },
     rejectedPlans: [] },
  serverInfo: 
   { host: 'VM-4-5-centos',
     port: 27017,
     version: '4.2.15',
     gitVersion: 'd7fd78dead621a539c20791a93abec34bb1be385' },
  ok: 1 }

其中,"stage": "IXSCAN" 表示基于索引的扫描。

4.2 覆盖的查询

当查询条件和查询的投影仅包含索引字段时,MongoDB 将直接从索引返回结果,而不扫描任何文档或将文档带入内存,这些覆盖的查询可以非常有效。2e718f6de6d94987ae2f2182c528d9c8.png

>db.comment.find({userid:"1003"},{userid:1,_id:0})
{ userid: '1003' }
{ userid: '1003' }
>db.comment.find({userid:"1003"},{userid:1,_id:0}).explain()
{ queryPlanner: 
   { plannerVersion: 1,
     namespace: 'article.comment',
     indexFilterSet: false,
     parsedQuery: { userid: { '$eq': '1003' } },
     winningPlan: 
      { stage: 'PROJECTION_COVERED',
        transformBy: { userid: 1, _id: 0 },
        inputStage: 
         { stage: 'IXSCAN',
           keyPattern: { userid: 1 },
           indexName: 'userid_1',
           isMultiKey: false,
           multiKeyPaths: { userid: [] },
           isUnique: false,
           isSparse: false,
           isPartial: false,
           indexVersion: 2,
           direction: 'forward',
           indexBounds: { userid: [ '["1003", "1003"]' ] } } },
     rejectedPlans: [] },
  serverInfo: 
   { host: 'VM-4-5-centos',
     port: 27017,
     version: '4.2.15',
     gitVersion: 'd7fd78dead621a539c20791a93abec34bb1be385' },
  ok: 1 }
相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。   相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
相关文章
|
17天前
|
监控 NoSQL MongoDB
【MongoDB】MongoDB 索引
【4月更文挑战第1天】【MongoDB】MongoDB 索引
|
17天前
|
存储 NoSQL 关系型数据库
|
8月前
|
NoSQL MongoDB 索引
【最佳实践】MongoDB导入数据时重建索引
【最佳实践】MongoDB导入数据时重建索引
203 0
|
9月前
|
JSON NoSQL MongoDB
mongodb基本操作,增删改查,查询,索引,权限机制
mongodb基本操作,增删改查,查询,索引,权限机制
|
8月前
|
NoSQL MongoDB 索引
开心档-软件开发入门之MongoDB 覆盖索引查询
开心档-软件开发入门之MongoDB 覆盖索引查询
49 0
|
8天前
|
NoSQL MongoDB 数据库
MongoDB的索引与索引字段的顺序
MongoDB的索引与索引字段的顺序
21 2
|
10天前
|
NoSQL MongoDB 数据库
通过优化索引以消除 MongoDB 中的 "查询目标已超过1000个扫描对象/返回的文档数" 警告
MongoDB NoSQL数据库在处理复杂查询时可能出现“查询目标已超过1000个扫描对象/返回的文档数”警告。文章分析了该问题,展示了一个示例集合和相关索引,并提供了查询示例。通过`explain`命令发现查询未有效利用索引。解决方案是遵循ESR规则,创建新索引从而优化查询并消除警告。
39 1
|
17天前
|
NoSQL 测试技术 定位技术
【MongoDB 专栏】MongoDB 的地理空间索引与位置查询
【5月更文挑战第10天】MongoDB 支持地理空间数据处理,提供2dsphere(球面)和2d(平面)索引,适用于地图导航、物流、社交网络等领域。通过创建索引,可加速位置查询,如查询范围、最近邻及地理空间聚合。案例包括地图应用、物流追踪和社交网络。注意数据准确性、索引优化和性能测试,以发挥其在地理空间处理中的潜力。学习此功能,为应用开发解锁更多可能性!
【MongoDB 专栏】MongoDB 的地理空间索引与位置查询
|
17天前
|
存储 NoSQL MongoDB
【MongoDB 专栏】如何高效使用 MongoDB 的索引
【5月更文挑战第10天】MongoDB的索引是提升查询性能的关键,它基于B树结构,分为单字段、复合、多键和文本索引。创建索引可通过`createIndex()`或管理工具,适用于频繁查询、排序分组和连接操作。优化策略包括选择合适字段、避免过度索引和定期评估。注意索引影响写入性能、大小限制及可能的失效情况。通过案例分析,应根据业务需求合理创建和使用索引,以实现最佳性能。
【MongoDB 专栏】如何高效使用 MongoDB 的索引
|
17天前
|
存储 NoSQL 关系型数据库
【MongoDB系列笔记】索引
索引支持在MongoDB中高效地执行查询。如果没有索引,MongoDB必须执行全集合扫描,即扫描集合中的每个文档,以选择与查询语句匹配的文档。这种扫描全集合的查询效率是非常低的,特别在处理大量的数据时,查询可以要花费几十秒甚至几分钟,这对网站的性能是非常致命的。
25 1