2012-03-20 32 views
3

我有一個收集 「數字」 與200000文檔對象與{號:ⅰ} i = 1到200000搜索時間>而不索引

在沒有任何索引$ GT:10000給出nscanned 200000個115毫秒。 使用索引號$ gt:10000可掃描189999和355 ms。

爲什麼更多的時間與索引?

> db.numbers.find({number: {$gt: 10000}}).explain() 
{ 
    "cursor" : "BasicCursor", 
    "nscanned" : 200000, 
    "nscannedObjects" : 200000, 
    "n" : 189999, 
    "millis" : 115, 
    "nYields" : 0, 
    "nChunkSkips" : 0, 
    "isMultiKey" : false, 
    "indexOnly" : false, 
    "indexBounds" : { 

    } 
} 

> db.numbers.ensureIndex({number: 1}) 

> db.numbers.find({number: {$gt: 10000}}).explain() 
{ 
    "cursor" : "BtreeCursor number_1", 
    "nscanned" : 189999, 
    "nscannedObjects" : 189999, 
    "n" : 189999, 
    "millis" : 355, 
    "nYields" : 0, 
    "nChunkSkips" : 0, 
    "isMultiKey" : false, 
    "indexOnly" : false, 
    "indexBounds" : { 
      "number" : [ 
        [ 
          10000, 
          1.7976931348623157e+308 
        ] 
      ] 
    } 
} 
+0

我試過很多次迭代,但不同的是幾乎與200ms的指數和指數沒有。 – 2012-03-20 17:53:33

回答

5

在這種情況下,索引不起作用,因爲您的匹配結果集幾乎包含整個集合。這意味着它必須加載到RAM中並遍歷大部分索引,並加載到RAM中並遍歷文檔本身。

沒有索引,它只會執行表掃描,檢查每個文檔並在匹配時返回。

在這種情況下,查詢將返回幾乎整個集合,索引可能沒有幫助。

添加.limit()將加快查詢速度。您還可以強制查詢優化器不使用索引與.hint():

db.collection.find().hint({$natural:1}) 

你也可以強制查詢直接從指數本身提供的結果值限制選定字段只有那些你已經索引。這使得它可以避免在索引掃描之後加載任何文檔。

試試這個,看看輸出解釋這裏所指"indexOnly":true

db.numbers.find({number: {$gt: 10000}}, {number:1}).explain() 

詳情:

http://www.mongodb.org/display/DOCS/Retrieving+a+Subset+of+Fields#RetrievingaSubsetofFields-CoveredIndexes

+0

很棒的信息,謝謝... – 2012-03-20 18:03:14