MongoDB 索引的使用

本文涉及的产品
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
简介: 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
相关文章
|
2月前
|
存储 NoSQL MongoDB
掌握MongoDB索引优化策略:提升查询效率的关键
在数据库性能调优中,索引是提升查询效率的利器。本文将带你深入了解MongoDB索引的内部工作原理,探讨索引对查询性能的影响,并通过实际案例指导如何针对不同的查询模式建立有效的索引。不仅将涵盖单一字段索引,还会探讨复合索引的使用,以及如何通过分析查询模式和执行计划来优化索引,最终实现查询性能的最大化。
|
4月前
|
监控 NoSQL MongoDB
MongoDB数据库的索引管理技巧
【8月更文挑战第20天】MongoDB数据库的索引管理技巧
86 1
|
5月前
|
NoSQL Java API
MongoDB 强制使用索引 hint
MongoDB 强制使用索引 hint
156 3
|
1月前
|
存储 NoSQL 关系型数据库
MongoDB索引知识
MongoDB索引知识
32 1
MongoDB索引知识
|
6月前
|
存储 监控 NoSQL
MongoDB索引解析:工作原理、类型选择及优化策略
MongoDB索引解析:工作原理、类型选择及优化策略
|
1月前
|
存储 NoSQL MongoDB
MongoDB 索引限制
10月更文挑战第22天
45 2
|
1月前
|
NoSQL MongoDB 索引
MongoDB 高级索引
10月更文挑战第22天
36 2
|
2月前
|
NoSQL MongoDB 索引
MongoDB 覆盖索引查询
10月更文挑战第21天
36 1
|
2月前
|
存储 NoSQL MongoDB
MongoDB 索引
MongoDB 索引
34 3
|
6月前
|
NoSQL 定位技术 MongoDB
深入探索 MongoDB:高级索引解析与优化策略
深入探索 MongoDB:高级索引解析与优化策略
196 1