2

MongoDB 索引用法与原理

 2 years ago
source link: https://wnanbei.github.io/post/mongodb-%E7%B4%A2%E5%BC%95%E7%94%A8%E6%B3%95%E4%B8%8E%E5%8E%9F%E7%90%86/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
MongoDB 索引用法与原理

从 MongoDB 3.2 开始,WiredTiger 成为 MongoDB 的默认存储引擎,WiredTiger 引擎使用 B+ 树作为索引的数据结构。

MongoDB 索引官方中文文档:MongoDB 索引

db.test.createIndex( { key1: 1 } )
  • 1 代表升序
  • -1 代表降序
db.test.createIndex( {"keypart1": 1, "keypart2": 1, "keypart3": 1} )

MongoDB 的复合索引也需要满足最左匹配原则。

为了索引包含数组值的字段,MongoDB 为数组中的每个元素创建一个索引键。这些多键索引支持对数组字段的高效查询。多键索引可以在包含标量值(例如字符串、数字)和嵌套文档的数组上构造。

创建方式与创建普通索引相同:

db.test.createIndex( { key1: 1 } )

从 MongoDB 3.4 开始,对于使用 MongoDB 3.4 或更高版本创建的多键索引,MongoDB 会跟踪哪个索引字段或哪些字段导致一个索引成为多键索引。

跟踪这些信息可以让 MongoDB 查询引擎使用更紧密的索引边界。

创建唯一索引:

db.members.createIndex( { "user_id": 1 }, { unique: true } )

对于一个范围分片集合,只有以下索引可以是唯一的:

  • 分片键上的索引。
  • 一个复合索引,其中片键是一个前缀。
  • 默认 _id 索引。如果 _id 字段不是分片键或分片键的前缀,_id 索引只对每个分片强制唯一性约束,而不是对所有分片强制唯一。

MonogDB 3.2 版本之后开始支持部分索引特性。

部分索引只索引集合中部分文档,部分索引可以降低存储需求,并降低创建和维护索引的性能成本。

db.restaurants.createIndex(
   { cuisine: 1, name: 1 },
   { partialFilterExpression: { rating: { $gt: 5 } } }
)

部分索引接受以下筛选条件:

  • field: value$eq
  • exists: true
  • $gt$gte$lt$lte
  • $type
  • $and 只在顶层操作符

使用唯一索引和部分索引的 exists:true 条件,可以让唯一索引在字段存在时才进行索引。

explain

explain 语句可以用来查看语句的执行计划:

db.test.find({"commonfield": "THctcu"}).explain("executionStats")

explain 语句有三种模式:

  1. queryPlanner - 默认模式,根据查询优化器的评估,选择一个最佳的查询计划。
  2. executionStats - 根据查询优化器的评估,选择一个最佳的查询计划执行,执行完毕后返回结果的统计信息。
    • 对于写操作,返回关于更新和删除操作的信息,但是并不将修改应⽤到数据库。
    • 对于被拒绝的执⾏计划,不返回其统计信息。
  3. allPlansExecution - 按照最佳的执⾏计划执⾏以及列出统计信息,还会列出⼀些候选的执⾏计划。
    • 如果有多个查询计划 ,executionStats 信息包括这些执⾏计划的部分统计信息。

explain 返回的信息较多,其中有一些比较重要的字段:

  • nReturned - 实际返回数据行数。
  • executionTimeMills - 语句执行时间,单位毫秒。
  • totalKeysExamined - 根据索引扫描的文档数量。
  • totalDocsExamined - 所有的文档扫描数量,如果与 totalKeysExamined 数量相同,说明所有扫描都走的索引。
  • stage - 查询的阶段类型,以下是可能的值:
    • COLLSCAN - 全表扫描
    • IXSCAN - 索引扫描
    • FETCH - 根据索引去主键索引查询对应文档
    • SORT - 内存中排序
    • LIMIT - 限制返回文档数量
    • SKIP - 跳过指定条数
    • SHARD_MERGE - 将各个分片返回的数据进行 merge
    • IDHACK - 根据 _id 进行查询
    • COUNT - 进行 count 运算
    • TEXT - 全文索引查询

概念与原理

由于 MongoDB 与 MySQL 都使用 B+ 树作为索引的数据结构,所以有一些概念是基本相通的。

MySQL 最左匹配

MySQL 索引下推

MySQL 覆盖索引

使用索引排序

索引本身是有序的,所以当 sort 排序条件与索引顺序一致时,sort 可以直接使用索引的查询结果,不需要做额外操作。而如果不能使用索引的顺序,那么额外需要在内存中进行排序操作。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK