MongoDB高效查询之索引机制

Posted 踩踩踩从踩

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MongoDB高效查询之索引机制相关的知识,希望对你有一定的参考价值。

Mongo高级用法_踩踩踩从踩的博客-CSDN博客

前言

本篇文章会继续介绍MongoDB高效查询中的索引机制,主要包括什么是索引、索引的作用,全面介绍MongoDB中索引,以及如何使用索引来优化查询,查询性能分析 多键索引,通配符索引,二维空间索引 ;在mongoDB中 索引来高效查询 ,如何操作管理索引;MangoDB中使用索引考虑的因素, 这都是MongoDB 如何高效查询的基础,虽然没有es那么强大,但也有自己的一套规则优化。

索引

索引是一种用来方便查询数据的数据结构。B Tree就是一种常用的数据库索引数据结构,MongoDB采用B树做索引,索引创建在colletions上。
MongoDB不使用索引的查询,先扫描所有的文档,再匹配符合条件的文档。
使用索引的查询,通过索引找到文档,使用索引能够极大的提升查询效率。
在磁盘中存数据,也是在无序的情况,没有索引 效率是非常低的。

这个在 二叉 以及 平衡树中,保证数据查询快速,以及平衡度的,左平衡和右平衡。这都是在索引下面 保证查询 ,但插入时会降低效率了。

一般这个索引的节点都会有 列值和行地址。 

 

MongoDB中的索引类型

它有自己比较特色的索引,包括单字段索引,在添加数据时,就会默认创建索引。

 

不同于传统的B-树索引,哈希索引使用hash函数来创建索引 在索引字段上进行精确匹配,但不支持范围查询,不支持多键hash; Hash索引上的入口是均匀分布的,在分片集合中非常有用;
hash索引 但是没有顺序性,没有范围概念。

MongoDb中如何创建索引

MongoDB使用 createIndex() 方法来创建索引, createIndex()方法基本语法格式如下所示:

// 创建索引的语法
db.collection.createIndex(keys, options)
  • keys 文档类型值
为要创建的索引字段,1为指定按升序创建索引,如果你想按降序来创建索引指定为-1。
  • options 文档类型值
MongoDB中提供了丰富的属性,比如
background,是否后台构建索引, 数据量太大时构建索引消耗时间长,为了不影响业务,加上
此参数,后台运行同时还会为其他读写操作让路。 name,自定义索引名字

 

/* 复合索引,索引的顺序跟查询排序相关联 */
db.inventory.createIndex(status:1, qty:-1);
// 上面的索引一升一降,查询排序的模式必须与索引键的模式匹配或逆向
status:-1, qty:1
status:1, qty:-1
db.inventory.find().sort(status:1, qty:-1).explain();
db.inventory.find().sort(status:-1, qty:1).explain();
// 下面的模式就不能够命中
status:1, qty:1
status:-1, qty:-1

/*多键索引,数组索引*/
db.inventory.createIndexes();
// 两个及以上多键索引,无法做复合索引

这种复合索引的模式,就和关系型数据库中索引就很像了。

复合索引,还有前缀匹配。这个

针对数组  而提出的 多键索引。

/* 单字段索引,根据物品名称查询物品 */
db.inventory.createIndex(item:1);

索引属性

这都是mongodb中比较特色的点,

  • 唯一索引
可确保索引字段不会存储重复值。MongoDB默认在创建集合时会在_id字段上创建唯一索引。
db.collection.createIndex(id:1, unique:true )
  • 部分索引
仅索引集合中符合指定过滤器表达式的文档。较低的存储需求,索引创建和维护的成本变小。
db.restaurants.createIndex( cuisine: 1, name: 1 , partialFilterExpression: rating:$gt: 5 )
  • 稀疏索引
仅索引包含具有索引字段的文档,哪怕索引字段包含空值
db.addresses.createIndex( "xmpp_id": 1 , sparse: true )
  • TLL索引
特殊的单字段索引,在一定时间后或在特定时间自动从集合中删除文档。对于日志和会话类的信息很有用。
db.eventlog.createIndex( "lastModifiedDate":1, expireAfterSeconds:3600 )

 这种属于添加了过期机制的。 删掉数据。

  • 不区分大小写
db.fruit.createIndex( type: 1,collation: locale:'en', strength:2 )

这对比前面的索引的。都是以简单方式 2进制进行对比的。 这里可以设置英语  法语这些支持。

MongoDB中的索引  

一般索引

单字段索引

有序的数据存储结构。 最小 最大的索引 可以正着走 反着走,单字段索引 灵活度是很强的。

 读和写都是基于内存的

复合索引,文档中所有键的指定排序 方向必须与索引键模式匹配或匹配索 引键模式的逆向

可以对调着走。

尽量少建索引,因为会降低写的性能的。

多键索引

多键索引,或可以称为数组索引。

文档的多个待索引字段是数组, 不能创建两个多键值字段的复合索引 ,复合索引只能包含一个字段是多键索引。 MongoDB是文档型数据库,两个字段为数组,这个情况是可以发生改变的,比如其中一个为数组,另一个不是数组。

通配符索引

MongoDB支持动态的文档结构,通过通配符索引应用程序可以查询事先未知字段。
// 创建索引的语法
 "userMetadata" :  "likes" : [ "dogs", "cats" ]  
 "userMetadata" :  "dislikes" : "pickles"  
 "userMetadata" :  "age" : 45  
 "userMetadata" : "inactive" 
通过$**来匹配uesrMetadata后面未知的字段
db.userData.createIndex(  "userMetadata.$**" : 1  )

根据内容通配符去创建索引,

二维空间索引

MongoDB中有两种二维平面索引:2d、geoHaystack。
  • 2d,对在二维平面上坐标点为存储的数据使用索引,是2.2版本中的坐标对。
  • GeyHaystack索引是一个特殊的索引,该索引被优化以在较小的区域上返回结果。GeHaystack索引提高了使 用平面几何图形的查询的性能。

 平面坐标对的形式

// 数组形式,推荐使用
location: [-73.856077, 40.848447] 
// 内嵌文档形式,第一个为经度,第二个为纬度,忽略字段名
location:  field1: -73, field2: 41,6 
空间索引总是稀疏的,并且忽略稀疏选项,仅支持简单的二进制比较。

空间索引总是稀疏的,并且忽略稀疏选项,仅支持简单的二进制比较。

球体空间索引

球体空间索引,2dsphere。支持好像地球球体上的位置,可以存放GeoJSON、传统坐标类型的数据。
GeoJSON数据 ,需要使用嵌入式文档存放,coordinates指定坐标位置,type指定坐标类型
Type有point/lineString/polygon 3种形式。
传统坐标数据 ,一个字段即可指定坐标位置。
上面的两种类型数据,经纬度的存储方式必须是[经度,纬度]的数组形式。

 

 

这种球体的方式,可以创建比较大的空间。

Hash索引

Hash索引通过索引字段值的散列来维护索引数据,使用哈希函数来计算索引字段值的哈希,
主要使用在分片键上。需要注意的点:
  • 支持任意单字段的Hash索引,不能创建多键的Hash索引
  • Hash值会发生碰撞,Hash索引不能设定为唯一约束
  • 支持相等查询,不支持范围查询
  • 创建hash索引的字段也可以创建其他索引
  • hashed索引不支持不能转换为64位整数的浮点值,大于2的53次方的浮点值
// 创建一个hash索引
db.collection.createIndex(  field: "hashed"  )

使用索引考虑的因素 

使用MongoDB中的索引,考虑的因素如下:

对应用程序的查询有深刻的理解 确定将要运行的查询的类型,以便可以构建引用这些字段的索引

  • 通过索引来提高查询效率 当索引包含该查询扫描的所有字段时,该索引就支持该查询
  • 通过索引对查询结果进行排序 为了支持有效的查询,在指定索引字段的顺序和排序顺序时
  • 确保索引有足够的内存 内存有限的情况下,MongoDB通过保存最近的值来淘汰老值
  • 使用能够覆盖索引的查询 查询使用索引缩小结果范围,可以限制可能检索的文档数量

 管理索引的话 直接用下面的命令就行。

 

以上是关于MongoDB高效查询之索引机制的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB 索引

详解MongoDB索引优化

笔记

笔记

mongoDB_08索引的操作

mongoDb地理空间索引和查询