2012-03-20 3 views
3

J'ai une collection "numéros" avec 200000 objet document avec {numéro: i} i = 1 à 200000temps de recherche avec index> sans index

Sans index $ gt: 10000 donne nscanned 200000 et 115 ms . Avec l'index sur le nombre $ gt: 10000 donne nscanned 189999 et 355 ms.

Pourquoi plus de temps avec l'indexation?

> 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

i essayé tant de fois, mais la différence est presque 200ms avec l'index et sans index. –

Répondre

5

Dans ce cas, l'index ne vous aide pas car votre jeu de résultats correspondant comprend la quasi-totalité de la collection. Cela signifie qu'il doit charger dans RAM et traverser la majeure partie de l'index, ainsi que charger dans RAM et traverser les documents eux-mêmes.

Sans l'index, il suffit de faire une analyse de table, en inspectant chaque document et en revenant s'il est apparié.

Dans les cas comme celui-ci où une requête va retourner presque toute une collection, un index peut ne pas être utile. L'ajout d'un .limit() accélérera l'interrogation.

Vous pouvez également forcer l'optimiseur de requêtes de ne pas utiliser l'index avec .hint():

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

Vous pouvez également forcer la requête à fournir les valeurs de résultat directement à partir de l'indice lui-même en limitant les champs sélectionnés aux seuls ceux vous avez indexé. Cela lui permet d'éviter le besoin de charger des documents après l'analyse de l'index.

Essayez et voir si l'expliquer sortie indique "indexOnly":true

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

Détails ici:

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

+0

bonne information, merci ... –