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

引用 DOCs :

< Buff行情>

创建索引时,与键关联的数字指定索引的方向,因此它应该始终为1(升序)或-1(下降)。方向对于单键索引或随机存取检索,但重要的是,如果你正在做排序或对复合索引的范围查询。

然而,我认为没有理由认为,在复合索引上,索引的方向应该很重要。有人能提供进一步的解释(或一个例子)吗?

2017-06-13 12:55:39  Rahul Kumar

A回答

  • 1

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

    <强>当发现单个项>时,树中节点的顺序是无关的。

    < >强>如果返回一个节点范围>强>,相邻的元素将落在树的同一个分支上。节点在范围内的距离越近,检索它们的速度就越快。

    使用单个字段索引-顺序无关紧要。如果它们以升序接近,它们也将以降序接近。

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

    例如,如果键是升序b,则索引可能如下所示:

    A排B排11月1日2 2 6个3 2 7个4 3 4个5 3 5个6 3 6个7 5 1个

    查询升序B降序将需要跳转到索引周围,以便返回行,而且速度会慢一些。例如,它将返回行1, 3, 2, 6, 5, 4, 7

    与索引相同的远程查询将按正确顺序顺序返回行。

    在BTURE中查找记录需要O(log(n))时间。按顺序查找一系列记录仅为olog(n)+k,其中k是要返回的记录数。

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

    2013-04-21 18:09:39  shlensky Jared Kells
  • 2

    您要寻找的简单答案是,方向仅在您对两个或多个字段进行排序时才重要

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

    索引{a : 1, b : 1}将比索引{a : 1, b : -1}

    2019-03-15 15:24:10  Zaid Masud
    • 1
      为什么?@扎伊德 – Mark Pieszak - Trilon.io Nov 5 '15 at 13:43
    • 1
      < StaseCype =“注释副本”> @ MarkPieszak,因为整个类型必须在内存中完成,使得索引无用 – Sammaye Nov 5 '15 at 17:09
    • @sammaye我认为这是一个正确的想法,尽管我不确定它是否是整个排序。I&A 39;D必须查看实现,知道它是如何工作的,但是我认为,结果可以单独由 A/i>排序,然后附加的 b排序需要在内存中完成。 – Zaid Masud Nov 5 '15 at 18:07
    • 1
      < StaseCype =“注释副本”> HMM,奇怪的是,上次我检查代码时,由于排序是MEH,它放弃了部分排序,也许它和Y 39改变了< /SPAN >。 – Sammaye Nov 5 '15 at 18:20
    • 如果我在{a: -1, b: -1}上排序,我应该有{a: -1, b: -1}索引还是{a: 1, b: 1}就足够了。 – Hussain Mar 22 '17 at 9:35
    • @hussain在您的示例中,{a: 1, b: 1}索引应该足够,因为完全反转索引是可以的。例如,{a: 1}上的索引可用于{a: -1}上的排序 – Zaid Masud Sep 1 '17 at 18:26
  • 3

    为什么索引

    理解两个要点。

    1. 虽然一个索引比没有索引好,但正确的索引要比任何一个好得多。
    2. 每一个查询只使用一个索引,用适当的字段排序你可以使用的索引。

    索引不是免费的。它们占用内存,并在插入、更新和删除时强制执行性能惩罚。通常,性能命中率可以忽略不计(特别是与读取性能相比),但这并不意味着我们不能很聪明地创建索引。

    如何索引

    确定哪些字段组应该被索引在一起是关于理解您正在运行的查询。用于创建索引的字段的顺序至关重要。好消息是,如果您弄错了顺序,索引将不会被使用,因此很容易找到explain。

    为什么排序

    您的查询可能需要排序。但是排序可能是一个昂贵的操作,所以处理你正在排序的字段就像你正在查询的字段是很重要的。所以如果有索引的话会更快。但是有一个重要的区别,您排序的字段必须是索引中的最后一个字段。此规则的唯一例外是,如果字段也是查询的一部分,则必须是最后一个规则不适用。

    如何排序

    您可以在索引的所有键或子集上指定排序;但是,排序键必须与索引中显示的顺序相同。例如,索引键模式{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 }
    
    2018-02-19 05:45:57  recoder Somnath Muluk