2013-10-22 44 views
3

考慮以下蒙戈索引策略和查詢,爲什麼MongoDB不能使用與查詢非常相似(不精確)的複合索引?

指數:

db.collec.ensureIndex({a:1,b:1,c:1}); 

查詢:

db.collec.find({"a":"valueA"},{"_id":0,"a":1,"c":1}).sort({"c":-1}).limit(150) 

上述查詢返回的解釋:

/* 0 */ 
{ 
    "cursor" : "BtreeCursor a_1_b_1_c_1", 
    "isMultiKey" : false, 
    "n" : 150, 
    "nscannedObjects" : 178, 
    "nscanned" : 178, 
    "nscannedObjectsAllPlans" : 279, 
    "nscannedAllPlans" : 279, 
    "scanAndOrder" : true, 
    "indexOnly" : true, 
    "nYields" : 0, 
    "nChunkSkips" : 0, 
    "millis" : 1, 
    "indexBounds" : { 
     "a" : [ 
      [ 
       "valueA", 
       "valueA" 
      ] 
     ], 
     "b" : [ 
      [ 
       { 
        "$minElement" : 1 
       }, 
       { 
        "$maxElement" : 1 
       } 
      ] 
     ], 
     "c" : [ 
      [ 
       { 
        "$minElement" : 1 
       }, 
       { 
        "$maxElement" : 1 
       } 
      ] 
     ] 
    } 
} 

的這裏的問題是 其清晰y表示查詢完全在索引上運行(如"indexOnly" : true)。 但是爲什麼"scanAndOrder" : true
根據Btree索引模型,c是在索引的尾部,因此它可以用於排序。沒有?

爲什麼不使用它?

回答

0

如果您使用下面的索引掃描並且順序將是錯誤的。

db.collec.ensureIndex({a:1,c:-1,b:1});

Check this out

+0

是的,我接受。但索引不是專門用於此查詢,它已經在那裏,我正在做這個查詢的第一次。僅供參考,更改索引會影響查詢,具體取決於索引。我的問題是爲什麼它不能使用索引來排序,即使c在索引的尾部? –

5

這是正確的,也documented

至於爲什麼:索引看起來基本上是這樣的樹:

  • 一個: 「值A」
    • B: 「ABC」
      • C:435
      • C:678
    • B:「BCD」
      • C:123
      • C:993

正如你所看到的,排序是正確的,上升的,但如果你採取階c值不限制到固定的b的子集,你會得到[435, 678, 123, 993],這是不正確的,所以scanAndOrder是必需的。

不幸的是,沒有index intersectioning的索引非常不靈活。

+1

可能還好添加:https://jira.mongodb.org/browse/SERVER-3071越多宣傳越有可能mongodb inc可能會實施它 – Sammaye

+0

好點!我添加了答案的鏈接,因爲很多人可能不知道這個詞,即使他們知道這個特徵。 – mnemosyn

相關問題