mongodb索引

默认索引

每个文档默认都有一个字段_id,这个字段会自动生成唯一索引,这个索引无法删除。这个字段的值可以是用户指定,如果不指定mongodb会自动生成。

生成的规则:

|<-- 4 -->|<- 3 ->|<-2->|<-- 3 -->|
+---------+-------+-----+---------+
|unix time| mid   | pid | counter |
+---------+-------+-----+---------+

包含四个字段:

  1. unix时间戳,4个字节
  2. 机器id,3个字节
  3. 进程id,2个字节
  4. 计数器,3个字节,自增,从一个随机数开始

索引类型

单字段索引

文档中的任何字段或者子文档的字段都可以当作索引,字段的值也可以是一个文档。

复合索引(compound index)

一个文档中的多个字段组成一个索引。最多支持31个字段。

Prefixes

当查询的条件是索引的前面几个字段时会使用复合索引。

比如:有索引{a:1,b:1,c:1},查询条件{a:"a",b:"b"}就会使用这个索引,但是{b:"b"}这样的查询条件就无法使用。

排序

索引的顺序先按第一个字段排序,如果第一个字段相等,按照第二个字段排序,依次类推后面的字段顺序。因此,

  1. 如果有以下索引{a:1,b:1},支持排序{a:-1,b:-1}/{a:1:b:1},不支持排序{a:-1:b:1}/{a:1:b:-1}
  2. 只支持Prefixes的排序。

多值索引(multikey index)

字段的值是一个数组,就会自动把这个索引变成多值索引,支持范围查询。

地理空间索引(geospatial index)

包含两种索引:2d/2dsphere index

文本索引(text indexes)

作用于值是字符串或者是字符串数组的字段,查询字段中是否包含查询字符串。

哈希索引(hashed indexes)

用于基于hash的sharding。

交集索引(index intersection)

如果查询条件中出现使用了多个索引,包括Prefixes索引。mongodb可能会使用多个索引进行查询,然后取交集。是否使用了这个索引,可以通过explain来确定。

当查询需要排序,同时排序的字段需要的索引和查询条件无法组成一个或者部分query predicate,那就无法使用这个索引了。

比如:有索引{a:1}/{b:1,c:1},查询db.col.find({a:'a'}).sort({b:1})无法使用,虽然排序中包含字段b,但是查询条件中无法使用这个索引;而查询db.col.find({a:'a',b:'b'}).sort({c:1})却可以使用两个索引,这是因为查询条件中有{b:'b'}和排序字段{c:1},索引{b:1,c:1}组成部分查询条件。

索引的属性

唯一性

可以指定一个索引唯一。

部分索引(partial indexes)

只索引满足条件的文档,它是稀疏索引的超集,相比稀疏索引采用部分索引。

稀疏索引(sparse indexes)

只索引存在该字段值的文档。

TTL(time to live)索引

过期索引,针对值为日期或者日期数组的字段。如果字段值超过了过期日期,就会自动删除。过期时间可以动态修改的,有两种方式指定过期行为:

  1. 指定字段日期和过期时长。
  2. 指定过期日期,同时过期时长为0。

优化

  1. 如果查询的内容和条件都只引用索引时,那么只需要扫描索引数据,不需要查询文档内容。
  2. background构建,增量式构建索引。构建时,可以处理其他请求,但是构建索引的请求会被阻塞。

限制

  1. 每个index entry的大小不能超过1024字节,超过这个大小的文档会无法插入。
  2. 每个collection最多拥有64个索引。
  3. 索引名字长度 最多128字符,名字规范:..$ ,其中index name,默认是字段名字+类型,这个名字可以在创建索引的时候指定。
  4. 复合索引最多允许使用31个字段。
  5. 查询条件不能同时使用文本索引和地理空间索引。
  6. 2dsphere index的值只能是几何数据。
  7. 多值索引无法做cover query优化,比如:字段{a:[{b:1},{b:2}]}
  8. 地理空间索引无法做cover query优化。
  9. 构建索引的请求执行时构建会有一个内存限制,超过这个限制会使用临时文件。可以阀值可以修改。
  10. text/2d/geoHaystack索引无法使用collation。
← 分布式ID生成算法 接口在哪里定义? →
存档 关于