0%

MongoDB索引

MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。它是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型。Mongo最大的特点是它支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。

一、概念

      索引是特殊的数据结构,索引存储在一个易于遍历读取的数据集合中(索引存储在特定字段或字段集的值),而且是使用了B-tree结构。如果没有索引,MongoDB必须执行全集合collections扫描,即扫描集合中的每个文档,选取符合查询条件的文档document。如果查询时存在适当的索引,MongoDB可以使用索引来限制它必须查询的文档document的数量,特别是在处理大量数据时,所以选择正确的索引是很关键的、重要的。

二、存储引擎

  1. MMAPv1引擎:mongodb原生的存储引擎,比较简单,直接使用系统级的内存映射文件机制(memory mapped files),一直是mongodb的默认存储引擎,对于insert、read和in-place update(update不导致文档的size变大)性能较高;不过MMAPV1在lock的并发级别上,支持到collection级别,所以对于同一个collection同时只能有一个write操作执行,这一点相对于wiredTiger而言,在write并发性上就稍弱一些。对于production环境而言,较大的内存可以使此引擎更加高效,有效减少“page fault”频率,但是因为其并发级别的限制,多核CPU并不能使其受益。此引擎将不会使用到swap空间,但是对于wiredTiger而言需要一定的swap空间。(核心:对于大文件MAP操作,比较忌讳的就是在文件的中间修改数据,而且导致文件长度增长,这会涉及到索引引用的大面积调整)

  2. wiredTiger引擎:3.0新增引擎,官方宣称在read、insert和复杂的update下具有更高的性能。所以后续版本,我们建议使用wiredTiger。所有的write请求都基于“文档级别”的lock,因此多个客户端可以同时更新一个colleciton中的不同文档,这种更细颗粒度的lock,可以支撑更高的读写负载和并发量。因为对于production环境,更多的CPU可以有效提升wireTiger的性能,因为它是的IO是多线程的。wiredTiger不像MMAPV1引擎那样尽可能的耗尽内存,它可以通过在配置文件中指定“cacheSizeGB”参数设定引擎使用的内存量,此内存用于缓存工作集数据(索引、namespace,未提交的write,query缓冲等)。

三、原理

      当往某各个集合插入多个文档后,每个文档在经过底层的存储引擎持久化后会有一个位置信息,通过这个位置信息就能从存储引擎里读出该文档。比如MMAPv1引擎,位置信息是『文件id + 文件内offset 』,在wiredTiger存储引擎(一个KV存储引擎)里,位置信息是wiredtiger在存储文档时生成的一个key,通过这个key能访问到对应的文档。

四、分类

  1. 单列索引
  2. 复合索引
  3. 多key索引
  4. 全文索引
  5. hash索引

五、索引属性

  1. TTL索引(TTL Indexes)
  2. 惟一性索引(Unique Indexes)
  3. 部分索引(Partial Indexes)
  4. 稀疏索引(Sparse Indexes)

六、使用

  1. 添加索引

    • 语法db.collections.createIndex({key:order_type}[, options])

      • createIndex()用于3.0+版本,ensureIndex()用于3.0-以下版本
    • keys:要建立索引的参数列表,如:{KEY:1},其中key表示字段名,1表示升序排序,-1表示降序。

    • options:可选参数,表示建立索引的设置。可选值如下:

      • backgroundBoolean建索引过程会阻塞其它数据库操作,background可指定以后台方式创建索引,即增加 “background” 可选参数。 “background” 默认值为false。
      • uniqueBoolean建立的索引是否唯一。指定为true创建唯一索引。默认值为false.
      • namestring索引的名称。如果未指定,MongoDB的通过连接索引的字段名和排序顺序生成一个索引名称。
      • dropDupsBoolean3.0+版本已废弃。在建立唯一索引时是否删除重复记录,指定 true 创建唯一索引。默认值为false.
      • sparseBoolean对文档中不存在的字段数据不启用索引;这个参数需要特别注意,如果设置为true的话,在索引字段中不会查询出不包含对应字段的文档.。默认值为false.
      • expireAfterSecondsinteger指定一个以秒为单位的数值,完成 TTL设定,设定集合的生存时间。
      • vindex version索引的版本号。默认的索引版本取决于mongod创建索引时运行的版本。
      • weightsdocument索引权重值,数值在 1 到 99,999 之间,表示该索引相对于其他索引字段的得分权重。
      • default_languagestring对于文本索引,该参数决定了停用词及词干和词器的规则的列表。 默认为英语
      • language_override:string:对于文本索引,该参数指定了包含在文档中的字段名,语言覆盖默认的language,默认值为 language.
  2. 查看索引

    • db.collection.getIndexes() 查看集合中的索引
    • db.collection.totalIndexSize() 查看集合中的索引大小
    • db.system.indexes.find() 查看数据库中所有索引
    • getIndexKeys() 查看索引键
    • getIndexSpecs() 查看集合各索引的详细信息
  3. 删除索引

    • db.collection.dropIndexes() //删除所有索引
    • db.collection.dropIndex() //删除指定的索引
  4. 重建索引

    • db.collection.reIndex()

七、参考

  1. 参考一
  2. 参考二
  3. 参考三
  4. 参考四
  5. 参考五