2012-11-02 3 views
3

J'ai une requête OR que j'utilise actuellement pour une mise à jour semi-large. Essentiellement ma collection est divisée en deux ensembles de données;MongoDB OR indexation de condition

1 référentiel principal et 1 sous-ensemble du référentiel principal. Ceci est juste pour permettre une recherche plus rapide sur un petit sous-ensemble de données.

Je trouve cependant que ma requête que je crée pour extraire des choses dans le sous-ensemble arrive à expiration ... et quand on regarde l'explication, il semble que deux requêtes se produisent réellement.

PRIMARY> var date = new Date(2012,05,01); 
PRIMARY> db.col.find(
    {"$or":[ 
     {"date":{"$gt":date}}, 
     {"keywords":{"$in":["Help","Support"]}} 
    ]}).explain(); 

Ce produit:

{ 
"clauses" : [ 
    { 
     "cursor" : "BtreeCursor ldate_-1", 
     "nscanned" : 1493872, 
     "nscannedObjects" : 1493872, 
     "n" : 1493872, 
     "millis" : 1035194, 
     "nYields" : 3396, 
     "nChunkSkips" : 0, 
     "isMultiKey" : false, 
     "indexOnly" : false, 
     "indexBounds" : { 
      "ldate" : [ 
       [ 
        ISODate("292278995-01--2147483647T07:12:56.808Z"), 
        ISODate("2012-06-01T07:00:00Z") 
       ] 
      ] 
     } 
    }, 
    { 
     "cursor" : "BtreeCursor keywords_1 multi", 
     "nscanned" : 88526, 
     "nscannedObjects" : 88526, 
     "n" : 2515, 
     "millis" : 1071902, 
     "nYields" : 56, 
     "nChunkSkips" : 0, 
     "isMultiKey" : false, 
     "indexOnly" : false, 
     "indexBounds" : { 
      "keywords" : [ 
       [ 
        "Help", 
        "Help" 
       ], 
       [ 
        "Support", 
        "Support" 
       ] 
      ] 
     } 
    } 
], 
"nscanned" : 1582398, 
"nscannedObjects" : 1582398, 
"n" : 1496387, 
"millis" : 1071902 
} 

Y at-il quelque chose que je peux être indexation mieux faire de ce plus rapide? Semble juste moyen de ralentir ...

Merci d'avance!

+0

quel est votre indice? est juste une date déposée? – RameshVel

+0

J'ai essayé de créer des index séparés sur les mots-clés et la date; et essayé de les créer comme un index composé à travers les deux. – Petrogad

+0

Hmm Vous allez chercher des enregistrements de 1,4m là ... c'est un peu, vous pouvez essayer d'étendre le minuteur sur le curseur mongo pour une requête aussi grande. Aussi quelle est votre configuration ici?17m est un temps très long J'admets – Sammaye

Répondre

1

Un $or query évaluera chaque article séparément et combiner les résultats pour supprimer les doublons .. donc si vous souhaitez optimiser les requêtes que vous devriez d'abord essayer de explain() chaque clause individuellement.

Il semble qu'une partie du problème réside dans le fait que vous récupérez un grand nombre de documents tout en écrivant activement dans cette collection, comme en témoigne la valeur élevée nYields (3396). Il serait utile d'examiner la sortie mongostat lorsque la requête est en cours d'exécution afin de prendre en compte d'autres facteurs, tels que les erreurs de page, le% de verrouillage et les files d'attente de lecture/écriture.

Si vous voulez faire cette requête plus rapide pour un grand nombre de documents et des mises à jour de collecte très actifs, deux meilleures approches pratiques à prendre en compte sont les suivants:

1) préagrégation

Essentiellement ceci est mise à jour des statistiques agrégées lorsque les documents sont insérés/mis à jour afin que vous puissiez effectuer des requêtes en temps réel. Le manuel MongoDB décrit ce cas d'utilisation plus en détail: Pre-Aggregated Reports.

2) Carte incrémentielle/Réduire

Une approche incremental Map/Reduce peut être utilisé pour calculer les statistiques globales de lots successifs (par exemple, à partir d'une tâche cron horaire ou journalier). Avec cette approche, vous effectuez une Map/Reduce en utilisant l'option de sortie reduce pour enregistrer les résultats dans une nouvelle collection, et incluez un filtre query qui sélectionne uniquement les documents qui ont été créés/mis à jour depuis la dernière exécution de ce travail Map/Reduce.

0

Je pense que vous devriez créer un index composé sur la date et les mots-clés. Reportez-vous au poste ci-dessous pour plus de détails en fonction de votre cas d'utilisation

how to structure a compound index in mongodb

+0

Je l'ai fait; Cependant, il n'a pas semblé interroger quoi que ce soit plus rapide .. – Petrogad

+0

@Frederico voir ma mise à jour –

+0

juste vérifié; Cependant, il semble que les conditions OU touchent encore deux index. En supposant que cela allait le ralentir, il faudrait regarder le même indice deux fois, en n'utilisant que la moitié de l'information. – Petrogad

Questions connexes