mongodb 索引详解

使用springboot连接mongodb的时候,涉及到索引的使用
举例:

@Document(collection="book")
//注释的是复合索引
//@CompoundIndexes(
//        {
//                @CompoundIndex(name = "复合索引名字",def = "{'字段01':1,'字段02':1}")
//        })
public class book {//普通索引@Indexedprivate String name;
}

看了下关于索引的一篇翻译文章,

原文参考:mongoDB文档

转载内容如下:


      索引能够提高数据库的查询效率,没有索引的话,查询会进行全表扫描(scan every document in a collection),严重降低了查询效率。默认情况下,Mongo在一个集合(collection)创建时,自动地对集合的_id创建了唯一索引。

(NOTE:In sharded clusters, if you do not use the _id field as the shard key, then your application must ensure the uniqueness of the values in the _id field to prevent errors. This is most-often done by using a standard auto-generated ObjectId.)

1.索引的分类

   1.1单属性索引(Single Field)

针对单属性索引,排序顺序无关紧要,因为MongoDB能够在任意方向来回移动。

(For a single-field index and sort operations, the sort order (i.e. ascending or descending) of the index key does not matter because MongoDB can traverse the index in either direction.)

    单属性索引示例图:

详细信息:https://docs.mongodb.com/manual/core/index-single/

1.2 复合索引(Compound Index)

     针对单复合索引,索引中key的排序顺序决定了索引是否支持排序操作,举例子:

假如:一个对象包含username和date两个属性,如果创建索引如下:

    db.events.createIndex( { "username" : 1, "date" : -1 } )

则查询支持

    db.events.find().sort( { username: -1, date: 1 } )

    db.events.find().sort( { username: 1, date: -1 } ).

但是不支持如下查询:

    db.events.find().sort( { username: 1, date: 1 } ).

详细信息:https://docs.mongodb.com/manual/core/index-compound/ 。

1.3 多值索引(Multikey indexes)

    针对属性包含数组数据的情况,MongoDB支持针对数组中每一个element创建索引,Multikey indexes支持strings,numbers和nested documents。

  详细信息:https://docs.mongodb.com/manual/core/index-multikey/  。

1.4地理空间索引(Geospatial Index):

      针对地理空间坐标数据创建索引,类似于oracle geometry类型。

1.5 文本索引(Text Index)

      MongoDB提供了针对string内容的文本查询,Text Index支持任意属性值为string或string数组元素的索引查询。注释:一个集合仅支持最多一个Text Index。

详细信息:https://docs.mongodb.com/manual/core/index-text/

1.6 Hashed Index

     针对属性的哈希值进行索引查询,当要使用Hashed index时,MongoDB能够自动的计算hash值,无需程序计算hash值。注:hash index仅支持等于查询,不支持范围查询

2.索引属性

2.1 唯一索引(Unique Indexes)

  即不允许属性有重复的属性值。

2.2部分索引(Partial Indexes)(3.2版本新增)

    对集合中指定的筛选器表达式筛选后的部分集合进行创建索引,优点:减少了存储空间,提高的查询效率。

2.3 稀疏索引

    索引只保存一定条目的索引属性值,跳过没有被指定属性;当使用3.2之后的Mongo版本时,应优先考虑Partial Indexes。

(Changed in version 3.2: Starting in MongoDB 3.2, MongoDB provides the option to create partial indexes. Partial indexes offer a superset of the functionality of sparse indexes. If you are using MongoDB 3.2 or later, partial indexes should be preferred over sparse indexes.)

2.4 TTL索引

    TTL索引是特殊的索引,MongoDB能够在指定时间之后自动的删除集合中的数据,主要应用场景为机器产生的事件数据、日志、会话信息等。

(TTL indexes are special indexes that MongoDB can use to automatically remove documents from a collection after a certain amount of time. This is ideal for certain types of information like machine generated event data, logs, and session information that only need to persist in a database for a finite amount of time.)

详细信息:https://docs.mongodb.com/manual/core/index-ttl/ 。

3.索引限制

     3.1 如果MongoDB的索引项超过索引限制,即1024 bytes,MongoDB将不会创建该索引,注:2.6版本之前能够创建索引,但是不能够对该documents进行索引;

    3.2 当试图插入一个包含索引项的属性超过1024 bytes的documents时,MongoDB将插入documents失败,并返回错误;注:2.6版本之前能够插入成功,但是不能够对该documents进行索引;

    3.3 当试图更新documents的属性时时,如果索引项的属性超过1024 bytes的,MongoDB将插入documents失败,并返回错误;注:2.6版本之前能够插入成功,但是不能够对该documents进行索引;

    3.4 如果documents存在某索引,其索引属性超过了索引限制,则任何更新该documents将会失败;

    3.5 针对分片的collections,当数据迁移时,如果数据块中包含索引属性超过了索引限制,数据块的迁移将会失败;

3.6 一个collections最多能够有64个索引;

3.7 针对索引的全名,包含命名空间和“.”分隔符,如:<database>.<collection name>.$<index name>,最多不超过128 characters;

3.8 针对复合索引,包含的索引属性不能够超过31个属性;

3.9 查询不能够同时使用文本索引和地理空间索引(Queries cannot use both text and Geospatial Indexes);

3.11 包含2d sphere属性的索引,只能够针对地理空间属性;

3.12 如果通过覆盖索引查询得到的属性值是NaN(Not a Number),则NaN的类型总是double类型;

(If the value of a field returned from a query that is covered by an index is NaN, the type of that NaN value isalways double);

3.13 multikey index不支持covered query。

4.交叉索引

    MongoDB可以使用多个索引的交叉来满足查询,通常每个交叉索引包含两个索引,但是MongoDB能够使用多个或嵌套索引交叉来实现查询。

4.1 索引前缀交叉

    针对交叉索引,MongoDB能够使用交叉索引中任意一个索引的整个索引或者索引的前缀,索引前缀是指一个复合索引中索引的子集,由第一个或者前N个索引属性中的组成;

举例:

索引项如下:

{ qty: 1 }  { status: 1, ord_date: -1 }

MongoDB能够使用如下索引:

db.orders.find( { qty: { $gt: 10 } , status: "A" } )

4.2 索引交叉与复合索引

    索引交叉并不意味着复合索引没必要存在,因为属性在索引中的排列顺序和排序方式能够影响到复合索引,复合索引不支持不包含索引前缀或者不同的排序方式的查询情况(a compound index may not support a query condition that does not include theindex prefix keys or that specifies a different sort order)

举例:

如果复合索引如下:

{ status: 1, ord_date: -1 }

复合索引支持如下查询:

db.orders.find( { status: { $in: ["A", "P" ] } } )

db.orders.find( { ord_date: { $gt: new Date("2014-02-01") }, status: {$in:[ "P", "A" ] } })

但不支持如下查询:

db.orders.find( { ord_date: { $gt: new Date("2014-02-01") } } )db.orders.find( { } ).sort( { ord_date: 1 } )

但是如果collections包含如下索引:

{ status: 1 } { ord_date: -1 }

这两个索引,可以通过单独或者交叉支持以上4中查询。

4.3 索引交叉和排序

    索引交叉不支持排序操作,即要求一个索引安全的从查询谓语分离出来的排序;

举例:collections包含如下索引:

{ qty: 1 }

{ status: 1, ord_date: -1 }

{ status: 1 }

{ ord_date: -1 }

MongoDB不支持如下带有排序的交叉索引:

db.orders.find( { qty: { $gt: 10 } } ).sort( { status: 1 } )

That is, MongoDB does not use the { qty: 1 } index for the query, and the separate { status: 1 }or the { status: 1, ord_date: -1 } index for the sort.

5. 查询计划

     MongoDB查询优化器执行查询,并针对现有的索引选择最高效的查询计划,查询系统在每次查询执行时使用查询计划,查询优化器仅缓存包含不止一种的可执行计划的查询计划情况。针对每一次查询,查询计划器从查询计划缓存中查询一条满足query shape的计划,如果不存在满足的计划,查询计划器将通过试用一段时间来进行评价,来产生候选查询计划。查询计划器选择胜出的计划,在查询计划缓存中创建一个查询计划,然后使用该计划产生查询结果。

(For each query, the query planner searches the query plan cache for an entry that fits the query shape. If there are no matching entries, the query planner generates candidate plans for evaluation over a trial period. The query planner chooses a winning plan, creates a cache entry containing the winning plan, and uses it to generate the result documents.If a matching entry exists, the query planner generates a plan based on that entry and evaluates its performance through a replanning mechanism. This mechanism makes a pass/fail decision based on the plan performance and either keeps or evicts the cache entry. On eviction, the query planner selects a new plan using the normal planning process and caches it. The query planner executes the plan and returns the result documents for the query)

     可以使用db.collection.explain()或者 the cursor.explain() 来查看一个查询的查询计划统计数据。

Query shape:即查询谓语,排序和预测详细计划(A combination of query predicate, sort, and projection specifications)。

查询计划器的执行逻辑如下:

注释:

    a. Catalog operations(比如index的删除或collection的删除)将刷新查询计划缓存;

    b. 当Mongod重启或者关闭后,查询计划器缓存将不复存在。

6. 索引过滤(Index Filters)

      Index Filters决定了优化器将为query shape评价那个索引,如果Index Filters中包含了该Index Filters,优化器将仅考虑执行Index Filters指定的索引(When an index filter exists for the query shape, MongoDB ignores the hint(). To see whether MongoDB applied an index filter for a query shape, check the indexFilterSet field of either thedb.collection.explain() or the cursor.explain() method.)

Index Filters仅影响了优化器评价哪一个索引优化器也可能仍然选择collection 扫描以得到最优查询计划。

索引过滤有些类似于Oracle的RBO: Rule-Based Optimization基于规则的优化器;

注释:

    a. 由于Index Filters覆盖了优化器的预期的行为和hint()方法,所以要有节制的使用index filters;

    b. Index filters在MongoDB关闭之后将不复存在,也可以使用命令删除Index Filters。

7.覆盖查询(Covered Queries)

     当一个查询的查询条件和查询计划中只包含索引属性时,MongoDB不需要扫描documents或者将documents调入内存中时,这样的查询效率将非常高。

当同时满足如下两个条件时,则该查询是Covered Queries:

      a. 查询中的所有属性都是索引的一部分(all the fields in the query are part of an index);

      b. 所有查询到的结果中的属性值,都在同一个索引中(all the fields returned in the results are in the same index)。

举例:


(文档中有写的有可能不准确的地方,附上了官方的英文,以方便阅读和纠正)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/499804.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mongodb数据库,批量插入性能测试记录

spring boot 框架下&#xff0c;操作mongodb数据库 maven&#xff1a;spring-data-mongodb:2.1.3.RELEASE mongo数据库用的是本地的mongo&#xff0c;所以环境不一样&#xff0c;可能结果不一样。但趋势应该是一样的。 测试保证每次批量插入时&#xff0c;库里的数据量都是一…

[转载] --- 数据库基本知识

里面的很多点&#xff0c;我之前都总结过&#xff0c;但是感觉这篇把这些都连起来了&#xff0c;总结的挺好&#xff0c;转载保存一下 【从入门到入土】令人脱发的数据库底层设计前言 说到数据库这个词&#xff0c;我只能用爱恨交加这个词来形容它。两年前在自己还单纯懵懂的时…

spring-boot发送邮件失败 AuthenticationFailedException: 535 Authentication Failed

发送邮件失败&#xff0c;平时一直是好的&#xff0c;突然有天开始失败了&#xff0c;最后是发现邮箱密码失效了。。。 有的邮箱&#xff0c;需要定期更改密码。

互联网广告行业(01)------ 初识了解DSP、SSP、ADX

最近有幸接触到公司的一个实时竞价系统&#xff0c;也算是公司的核心系统之一了&#xff0c;增加了很多新的知识&#xff0c;可能有点乱&#xff0c;先总结一波&#xff1a; 广告行业&#xff0c;先介绍概念 广告主&#xff1a;需要打广告的站点&#xff0c;一般就是卖东西的…

互联网广告行业(02)------OpenRTB(实时竞价)规范解读

RTB&#xff1a;(Real Time Bidding实时竞价)&#xff0c;RTB是一种广告交易的方式 OpenRTB&#xff1a;简单理解就是一个行业规范&#xff0c;是一个为了促进RTB方式广告的标准&#xff0c;有对应的api文档&#xff0c;大家都按照这个规范去传参数&#xff0c;那么发送方和接收…

[go]---从java到go(01)---基础与入门上手

为什么用go&#xff0c;就是为了快速响应并且高并发。 一样的逻辑&#xff0c;用java也能实现&#xff0c;但用go可能就比java快点。 如果你很熟练java了&#xff0c;那么学习go就会很快。 go的社区环境相比java没那么大&#xff0c;但一般问题都足够了。 go是谷歌出品&#xf…

[数据库] --- clickhouse

clickhouse是一个列式数据库&#xff08;系统&#xff09;。 官方文档 官网比较全&#xff0c;但也可以说比较杂&#xff0c;下面就是我个人的一些总结&#xff0c;以及在实际工作中的应用场景。 1.clickhouse适用场景 clickhouse主要适合那种大量数据做分析的场景。 一般数据…

消息队列(5):RocketMQ

介绍 RocketMQ是一款成熟的分布式消息中间件。 由阿里2012年开源&#xff0c;2017年成为Apache顶级项目。 源码是java写的。 高性能&#xff0c;低延迟&#xff0c;高可靠。历经多次双十一大促&#xff0c;整体很稳定。 RocketMQ对比其他mq的优势 对比kafka和Rabbitmq&#…

[错误记录] --- rocketmq批量消费设置参数的问题

rocketmq想支持批量消费&#xff0c;于是便设置以下参数&#xff1a; consumer.setConsumeMessageBatchMaxSize(1000);这样是正确的&#xff0c;但由于业务要求&#xff0c;还想再设置大点&#xff0c;于是设置成这样&#xff1a; consumer.setConsumeMessageBatchMaxSize(10…

阿波罗配置中心(apollo)的个人看法

阿波罗应该是近几年比较火的一个分布式配置中心了&#xff0c;说说我个人的理解&#xff0c;希望对一些人有用吧。 首先从使用者的角度想 我们怎么用配置中心的&#xff1f; 1.得有个页面&#xff0c;能有权限管理&#xff0c;能有创建配置key-value。 在阿波罗中&#xff…

消息队列(4):Kafka

介绍 kafka是一个支持分布式的消息系统&#xff0c;基于发布/订阅模式。 kafka由LinkedIn公司开发&#xff0c;2010年成为Apache顶级项目。 源码是由java写的。 基本概念 1、Broker kafka集群中的每台机器&#xff0c;都叫一个broker. 2、Topic&#xff08;主题&#xff0…

clickhouse的ReplacingMergeTree引擎实战

学习ReplacingMergeTree引擎&#xff0c;首先你得了解clickhouse的MergeTree引擎&#xff0c;因为ReplacingMergeTree引擎是MergeTree引擎的一个扩展版引擎&#xff0c;他拥有和MergeTree一样的功能&#xff0c;同时新增了一个删除相同主键数据的功能。 我们知道&#xff0c;cl…

clickhouse 分片

我们知道mysql数据库如果想做分片&#xff0c;需要使用第三方组件&#xff0c;这是因为mysql在设计之初就没有太多考虑分布式等问题。而clickhouse作为新生代性能之王&#xff0c;分片也是必须的功能。基本上从2015年之后的各种数据库也罢&#xff0c;框架也罢&#xff0c;都开…

[记录] ---阿里云java.io.IOException: Connection reset by peer的问题

项目部署到阿里云&#xff0c;突然报错&#xff0c;频繁的打印堆栈信息&#xff0c;一开始是把堆内存打满导致服务一直重启&#xff0c;调大堆内存后就不影响正常服务了&#xff0c;但还是一直打堆栈&#xff0c;虽说日志会自动清理&#xff0c;但一直打这个信息着实不好看。 最…

实用的java代码生成器,开箱即用(基于mybatisplus的AutoGenerator)

spring-boot工程下&#xff0c;自动生成代码&#xff0c;controller层&#xff0c;service层&#xff0c;mapper层。 根据数据库配置好的表&#xff0c;逆向生成实体类和各层结构 1、引入maven <dependency><groupId>com.baomidou</groupId><artifactId&…

mac/windows 端口占用解决记录

idea启动报错&#xff1a;端口占用 The port may already be in use or the connector may be misconfigured mac端口占用解决 zhangshuaideMacBook-Pro:~ zhangshuai$ lsof -i:8095 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME Google 375 zhangshuai 32u IPv6 0x…

skywalking(1) 基于opentracing规范的APM系统

skywalking是&#xff1a; 基于opentracing规范的APM系统 skywalking解决了什么问题&#xff1f; skywalking解决微服务架构下&#xff0c;多服务直接复杂的调用关系 了解dapper&#xff0c;分布式链路追踪系统 dapper又是谷歌论文&#xff0c;各公司又相继模仿。&#xff…

skywalking(4)

Byte Buddy库 统计方法调用时长 1、增强字节码 2、拦截器拦截 类似于spring的aop&#xff0c;只不过skywalking不能用aop&#xff0c;所以用Byte Buddy技术代替 Open Trace 整个trace调用&#xff0c;是由多个span组成的有向无环图&#xff08;就是调用关系图&#xff09;。…

kubernetes(k8s)

应用部署演进过程 我们从上图可以看到&#xff0c;应用越来越看重应用本身了&#xff0c;慢慢的不受物理机的差异&#xff0c;不受操作系统的差异&#xff0c;开发者可以花更多精力去到应用本身。 k8s概念 简单理解&#xff0c;k8s就是传统的云平台上的linux。 kubernetes是…

为什么要用Elasticsearch

概念 Elasticsearch 简称ES&#xff0c;是一个分布式全文检索引擎。 比如github的代码检索就是用了ES&#xff0c;百度也有用ES。 由于Lucene的api相对比较复杂&#xff0c;所以ES其实是对Lucene的封装简化&#xff0c;并且提供了一套比较简单的api文档。 es官网 使用场景 主…