索引的原理
当往某各个集合插入多个文档后,每个文档在经过底层的存储引擎持久化后,会有一个位置信息,通过这个位置信息,就能从存储引擎里读出该文档
MMAPv1:文件id+文件内offset
WiredTiger: WiredTiger在存储文档时生成的一个key,通过这个key能访问到对应 的文档。
CPU飙升了?半天还是没出结果?要想提升速度,你是否想起了索引!!
建立索引后,MongoDB会额外存储一份按age字段升序排序的索引数据,索引结构类似如下,索引通常采用类似btree的结构持久化存储,以保证从索引里快速找出某个age值对应的位置信息,然后根据位置信息就能读取出对应的文档。
索引就是将文档按照某个(或某些)字段顺序组织起来,以便能根据该字段高效的查询。索引的基本作用:搜索+排序
有了索引,至少能优化如下场景的效率:
查询,比如查询年龄为18的所有人。
更新/删除,将年龄为18的所有人的信息更新或删除,因为更新或删除时,需要根据条件先查询出所有符合条件的文档,所以本质上还是在优化查询。
排序,将所有人的信息按年龄排序,如果没有索引,需要全表扫描文档,然后再对扫描的结果进行排序。
当存在索引时,执行DML操作将会更慢(维护索引)。
MongoDB默认会为插入的文档生成_id字段(如果应用本身没有指定该字段),_id是文档唯一的标识,为了保证能根据文档id快递查询文档,MongoDB默认会为集合创建_id字段的索引。
索引的特性
索引存储在内存(RAM)中,应该确保该索引的大小不超过内存的限制。
如果索引的大小大于内存的限制,MongoDB会删除一些索引,这将导致性能下降。
索引扫描类型:
索引覆盖:如果所有需要的字段都在索引中,不需要额外的字段,就可以满足索引覆盖的要求,不再需要从数据页加载数据,这就是索引覆盖。
索引扫描
集合扫描
索引的限制
1、每个collection限制64个索引。
2、索引名的长度不能超过125个字符。
3、一个复合索引最多可以有31个字段。
4、所有索引字段是一个数组,不能使用索引覆盖查询。
5、正则表达式及非操作符,如$nin,$not等;算术运算符,如$mod,等;$where子句。
6、索引越多写性能越差,例如:一张频繁修改的collection ,其索引达到20-30索引性能严重瓶颈。
7、建立索引是一个IO密集型操作,特别是当你的集合很大的时候。包括MySQL在内的所有支持辅助索引的数据库系统都有这种情况。如果你需要在一个大集合上建立索引,可以考虑在后台建立它。
8、如果很少对集合进行读取,可以不使用索引
索引的类型
1、单字段索引
2、复合索引
3、多键索引
4、Hash索引
5、地理位图索引
6、TTL索引
7、全文索引