MongoDB索引使用

分类

MongoDB 中的索引与其他数据库系统中的索引类似。 MongoDB 在集合级别定义索引,并支持 MongoDB 集合中文档的任何字段或子字段的索引。 常见的有以下类型: 键索引、复合索引、多键索引、地理空间索引、全文本索引和哈希索引。

  1. 单键索引:在单个字段上面建立索引;

  2. 复合索引:复合索引支持在多个字段建立索引匹配查询;

  3. 多键索引:对数组或者嵌套文档的字段进行索引;

  4. 地理空间索引:对包含地理坐标的字段进行索引;

  5. 文本索引:对文本字段进行全文索引;

  6. 哈希索引:将字段值进行哈希处理后进行索引;

  7. 通配符索引:使用通配符对任意字段进行索引;

Indexes

创建/删除/隐藏

MongoDB 使用 createIndex() 方法来创建索引:

db.collection.createIndex(keys, options) 语法中 Key 值为你要创建的索引字段,1 为指定按升序创建索引,如果你想按降序来创建索引指定为 -1 即可。

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

db.col.createIndex({"a":1,"b":-1}) 删除索引:

db.collection.dropIndex 删除索引在底层直接删除文件,然后修改元数据

从 4.4 开始支持隐藏索引

db.collection.hideIndex(<index>) 在删除索引前,可以先隐藏索引,查看集群是否异常后,才真正删除索引, 可有效帮助业务判断索引是否可以删除。

MongoDB CRUD Operations

复合索引

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

举例子:

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

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

则查询支持

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

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

但是不支持如下查询:

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

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

索引分析

MongoDB 中的索引分析

避免回表

通俗的讲就是,如果索引的列在所需获得的列中(因为索引是根据索引列的值进行排序的,所以索引节点中存在该列中的部分值)或者根据一次索引查询就能获得记录就不需要回表,mongo 默认的查询过程中, 在索引 b 树上找到对应的 RecorId 上, 还需在数据 b 树找对应的文档,然后进行 bson 解析。 实际上如果用户所需要的信息在索引 b 树的 key 内已经包括了,后面的回表操作是多余的,尤其是在大文档的条件下, BSON 解析比较消耗性能。

那么 MongoDB 如何去避免回表呢?

我们可以在 MongoDB 中可以通过使用 project 来选择需要返回的字段,保证所需字段在 project 条件内,特别注意 MongoDB 默认_id 字段是需要返回的,如果确定不需要_id 字段,需要显式的指定_id 为 0,可以通过判断 explain 内是否包括 FETCH 阶段来判断是否发生了回表行为。

索引限制

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

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

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

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

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

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

  7. 针对索引的全名,包含命名空间和“.”分隔符,如:..$,最多不超过128 characters;

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

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

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

  11. 如果通过覆盖索引查询得到的属性值是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);

  12. multikey index不支持covered query。

参考