Answers:
MongoDB以某种方式连接复合键,并将其用作BTree中的键。
查找单个项目时 -树中节点的顺序无关紧要。
如果要返回一定范围的节点 -彼此靠近的元素将位于树的相同分支下。节点在范围内越近,可以更快地检索它们。
使用单个字段索引 -顺序无关紧要。如果它们以升序排列在一起,则它们也将以降序排列在一起。
当您有复合键时 -顺序开始重要。
例如,如果键是A升序B升序索引可能看起来像这样:
AB行 1 1 1 2 2 6 3 2 7 4 3 4 5 3 5 6 3 6 7 5 1
对于A升序,B降序的查询,将需要在索引周围跳转,以无顺序返回行,并且查询速度会变慢。例如它将返回Row1, 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}
{a: -1, b: -1}
,应该有{a: -1, b: -1}
索引还是{a: 1, b: 1}
足够了。
{a: 1, b: 1}
索引应该足够,因为完全反转索引是可以的。例如,索引on {a: 1}
可以用于排序{a: -1}
了解两个要点。
索引不是免费的。它们占用内存,并且在执行插入,更新和删除操作时会降低性能。通常,性能的影响可以忽略不计(特别是与读取性能的提高相比),但这并不意味着我们不能聪明地创建索引。
确定应一起索引哪些字段组是关于了解正在运行的查询。用于创建索引的字段顺序至关重要。好消息是,如果您输入的订单错误,则根本不会使用该索引,因此很容易找到解释。
您的查询可能需要排序。但是排序可能是一项昂贵的操作,因此将要排序的字段与要查询的字段一样对待是很重要的。因此,如果有索引,它将更快。但是,有一个重要的区别,您要排序的字段必须是索引中的最后一个字段。此规则的唯一例外是,如果该字段也是您的查询的一部分,则必须遵循的最后一条规则不适用。
您可以在索引的所有键或子集上指定排序;但是,排序键必须按照它们在索引中出现的顺序列出。例如,索引键样式{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 }
{ a: 1, b: 1, c: 1 }
你真的需要索引{ a: 1}
和{ a: 1, b: 1}
或指数{ a: 1, b: 1, c: 1 }
涵盖所有情况?如果查询始终使用相同的排序:1 -1中没有排序
1, 3, 2, 6, 5, 4, 7
?