为什么索引的方向在MongoDB中很重要?
引述: 创建索引时,与键关联的数字指定 索引的方向,因此它应始终为1(升序)或-1 (下降)。方向对于单键索引或 随机访问检索,但如果您正在进行排序或 复合索引上的范围查询为什么索引的方向在MongoDB中很重要?,mongodb,performance,sorting,indexing,query-optimization,Mongodb,Performance,Sorting,Indexing,Query Optimization,引述: 创建索引时,与键关联的数字指定 索引的方向,因此它应始终为1(升序)或-1 (下降)。方向对于单键索引或 随机访问检索,但如果您正在进行排序或 复合索引上的范围查询 然而,我看不出索引的方向对复合索引有什么影响。是否有人可以提供进一步的解释(或示例)?MongoDB以某种方式连接复合键,并将其用作BTree中的键 查找单个项目时-树中节点的顺序无关 如果返回一系列节点-彼此靠近的元素将位于树的相同分支下。节点在范围内越近,检索它们的速度就越快 使用单个字段索引-顺序无关紧要。如果它们按升
然而,我看不出索引的方向对复合索引有什么影响。是否有人可以提供进一步的解释(或示例)?MongoDB以某种方式连接复合键,并将其用作BTree中的键 查找单个项目时-树中节点的顺序无关 如果返回一系列节点-彼此靠近的元素将位于树的相同分支下。节点在范围内越近,检索它们的速度就越快 使用单个字段索引-顺序无关紧要。如果它们按升序排列,它们也将按降序排列 当您有一个复合键时-顺序开始起作用 例如,如果键是升序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 1 1 2 2 6 3 2 7 4 3 4 5 3 5 6 3 6 7 5 1 对于升序B和降序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}
为什么索引慢
理解两个关键点
{ 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 }
生成的行可能应该是
1,3,2,6,5,4,7
?我仍然看不出它变慢的原因。只有算法应该是不同的(对于A中的每组值,它应该跳转到组的末尾,并以相反的顺序处理),但是由于MongoDB索引位于内存中,因此对速度没有明显的影响。此外,RDBMS对索引的方向一无所知,情况与afaik非常相似?它之所以会影响性能,是因为它不像简化的示例那样只是内存中的顺序列表。它实际上是一棵加权树。无序跳跃将涉及再次遍历树。RDM确实具有索引的顺序。从BTree中按顺序获取节点非常简单,只需沿着每个叶子移动,直到用完为止,然后向上移动一个级别,再向下移动下一个分支。它的O(n)的秩序,这是更多的CPU密集型。感谢进一步澄清。我检查了文档-确实可以指定索引方向,但该设置被忽略。@MarkPieszak,因为整个排序必须在创建索引的内存中完成useless@Sammaye我认为这是一个正确的想法,尽管我不确定它是否是全部。我必须查看实现才能知道它是如何工作的,但我认为结果可以单独按a排序,然后额外的b排序需要在内存中进行。嗯,奇怪的是,上次我检查代码时,它放弃了部分排序,因为排序是如何的,如果我在{a:-1,b:-1}
上排序,我应该有{a:-1,b:-1}
索引还是{a:1,b:1}
就足够了。@Hussain在你的例子中是{a:1,b:1}<