为什么在 MongoDB 中索引的方向很重要?

引用 医生的话:

创建索引时,与键关联的数字指定 方向,所以它应该总是1(升)或 -1 方向对于单键索引或 随机访问检索,但是如果您正在进行排序或 对复合索引的范围查询。

然而,我看不出为什么指数的方向对复合指数有影响。有没有人能提供一个进一步的解释(或例子) ?

31948 次浏览

MongoDB 以某种方式连接复合键,并将其用作 BTree 中的键。

当查找单个条目 -树中节点的顺序是不相关的。

如果返回一个节点范围 -相邻的元素位于树的相同分支上。节点在范围内越近,检索它们的速度就越快。

使用单个字段索引 -顺序不重要。如果它们按升序靠得很近,那么它们也会按降序靠得很近。

当您有一个复合键 -顺序开始起作用。

例如,如果键是 A 升 B 升,那么索引可能是这样的:

Row   A B
1     1 1
2     2 6
3     2 7
4     3 4
5     3 5
6     3 6
7     5 1

对 A 升 B 降的查询将需要在索引中跳转,以便返回行,而且速度会更慢。例如,它将返回 1, 3, 2, 6, 5, 4, 7

按照与索引相同的顺序排列的查询将按照正确的顺序顺序返回行。

在 BTree 中查找记录需要 O (Log (n))时间。按顺序查找记录的范围只是 OLog (n) + k,其中 k 是要返回的记录数。

如果记录出现故障,成本可能高达 OLog (n) * k

你要找的 答案很简单是方向 只有在对两个或多个字段进行排序时才有问题

如果你在 {a : 1, b : -1}上排序:

指数 {a : 1, b : 1}将是 慢于指数 {a : 1, b : -1}

为什么是索引

理解两个关键点。

  1. 虽然一个索引比没有索引要好,但是正确的索引比没有索引要好得多。
  2. MongoDB 每个查询只使用一个索引,使用适当的字段顺序创建可能需要使用的复合索引。

索引不是免费的。它们占用内存,并在执行插入、更新和删除操作时造成性能损失。通常情况下,性能损失可以忽略不计(特别是与读性能的提高相比) ,但这并不意味着我们不能明智地创建索引。

如何索引

确定应该将哪组字段索引在一起是关于理解正在运行的查询的。用于创建索引的字段的顺序至关重要。好消息是,如果你把顺序弄错了,索引根本不会被使用,所以很容易通过解释找到。

为什么要分类

您的查询可能需要排序。但是排序可能是一项昂贵的操作,因此将正在排序的字段视为正在查询的字段非常重要。所以如果有索引的话会更快。但是有一个重要的区别,您正在排序的字段必须是索引中的最后一个字段。此规则的唯一例外是,如果字段也是查询的一部分,则不适用“必须是最后一个”规则。

怎么分类

您可以对索引的所有键或子集指定排序; 但是,排序键必须按照它们在索引中出现的顺序列出。例如,索引键模式{ a: 1,b: 1}可以支持{ a: 1,b: 1}上的排序,但不支持{ b: 1,a: 1}上的排序。

排序必须为其所有键指定相同的排序方向(即升序/降序)作为索引键模式,或者为其所有键指定相反的排序方向作为索引键模式。例如,索引键模式{ a: 1,b: 1}可以支持{ a: 1,b: 1}和{ a: -1,b: -1}上的排序,但不支持{ a: -1,b: 1}上的排序。

假设有以下索引:

{ a: 1 }
{ a: 1, b: 1 }
{ a: 1, b: 1, c: 1 }


Example                                                    Index Used
db.data.find().sort( { a: 1 } )                            { a: 1 }
db.data.find().sort( { a: -1 } )                           { a: 1 }
db.data.find().sort( { a: 1, b: 1 } )                      { a: 1, b: 1 }
db.data.find().sort( { a: -1, b: -1 } )                    { a: 1, b: 1 }
db.data.find().sort( { a: 1, b: 1, c: 1 } )                { a: 1, b: 1, c: 1 }
db.data.find( { a: { $gt: 4 } } ).sort( { a: 1, b: 1 } )   { a: 1, b: 1 }