MongoDB索引使用
Contents
分类
MongoDB 中的索引与其他数据库系统中的索引类似。 MongoDB 在集合级别定义索引,并支持 MongoDB 集合中文档的任何字段或子字段的索引。 常见的有以下类型: 键索引、复合索引、多键索引、地理空间索引、全文本索引和哈希索引。
-
单键索引:在单个字段上面建立索引;
-
复合索引:复合索引支持在多个字段建立索引匹配查询;
-
多键索引:对数组或者嵌套文档的字段进行索引;
-
地理空间索引:对包含地理坐标的字段进行索引;
-
文本索引:对文本字段进行全文索引;
-
哈希索引:将字段值进行哈希处理后进行索引;
-
通配符索引:使用通配符对任意字段进行索引;
创建/删除/隐藏
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>)
在删除索引前,可以先隐藏索引,查看集群是否异常后,才真正删除索引, 可有效帮助业务判断索引是否可以删除。
复合索引
针对单复合索引,索引中key的排序顺序决定了索引是否支持排序操作:
举例子:
假如:一个对象包含username和date两个属性,如果创建索引如下:
|
|
则查询支持
|
|
和
|
|
但是不支持如下查询:
|
|
详细信息:https://docs.mongodb.com/manual/core/index-compound/ 。
索引分析
避免回表
通俗的讲就是,如果索引的列在所需获得的列中(因为索引是根据索引列的值进行排序的,所以索引节点中存在该列中的部分值)或者根据一次索引查询就能获得记录就不需要回表,mongo 默认的查询过程中, 在索引 b 树上找到对应的 RecorId 上, 还需在数据 b 树找对应的文档,然后进行 bson 解析。 实际上如果用户所需要的信息在索引 b 树的 key 内已经包括了,后面的回表操作是多余的,尤其是在大文档的条件下, BSON 解析比较消耗性能。
那么 MongoDB 如何去避免回表呢?
我们可以在 MongoDB 中可以通过使用 project 来选择需要返回的字段,保证所需字段在 project 条件内,特别注意 MongoDB 默认_id 字段是需要返回的,如果确定不需要_id 字段,需要显式的指定_id 为 0,可以通过判断 explain 内是否包括 FETCH 阶段来判断是否发生了回表行为。
索引限制
-
如果MongoDB的索引项超过索引限制,即1024 bytes,MongoDB将不会创建该索引,注:2.6版本之前能够创建索引,但是不能够对该documents进行索引;
-
当试图插入一个包含索引项的属性超过1024 bytes的documents时,MongoDB将插入documents失败,并返回错误;注:2.6版本之前能够插入成功,但是不能够对该documents进行索引;
-
当试图更新documents的属性时时,如果索引项的属性超过1024 bytes的,MongoDB将插入documents失败,并返回错误;注:2.6版本之前能够插入成功,但是不能够对该documents进行索引;
-
如果documents存在某索引,其索引属性超过了索引限制,则任何更新该documents将会失败;
-
针对分片的collections,当数据迁移时,如果数据块中包含索引属性超过了索引限制,数据块的迁移将会失败;
-
一个collections最多能够有64个索引;
-
针对索引的全名,包含命名空间和“.”分隔符,如:..$,最多不超过128 characters;
-
针对复合索引,包含的索引属性不能够超过31个属性;
-
查询不能够同时使用文本索引和地理空间索引(Queries cannot use both text and Geospatial Indexes);
-
包含2d sphere属性的索引,只能够针对地理空间属性;
-
如果通过覆盖索引查询得到的属性值是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);
-
multikey index不支持covered query。