web-dev-qa-db-fra.com

MongoDB {agrégation $ match} vs {find} vitesse

J'ai une collection mongoDB avec des millions de lignes et j'essaie d'optimiser mes requêtes. J'utilise actuellement le cadre d'agrégation pour récupérer des données et les regrouper comme je le souhaite. Ma requête d'agrégation typique est quelque chose comme: $match > $group > $ group > $project

Cependant, j'ai remarqué que les dernières parties ne prennent que quelques ms, le début est le plus lent.

J'ai essayé d'effectuer une requête avec uniquement le filtre $ match, puis d'exécuter la même requête avec collection.find. La requête d'agrégation prend ~ 80 ms tandis que la requête de recherche prend 0 ou 1 ms.

J'ai des index sur à peu près chaque champ, donc je suppose que ce n'est pas le problème. Une idée sur ce qui pourrait mal tourner? Ou s'agit-il simplement d'un inconvénient "normal" du cadre d'agrégation?

Je pourrais utiliser des requêtes de recherche au lieu de requêtes d'agrégation, mais je devrais effectuer beaucoup de traitement après la demande et ce processus peut être fait rapidement avec $group etc. donc je préfère garder le cadre d'agrégation.

Merci,

MODIFIER :

Voici mes critères:

{
    "action" : "click",
    "timestamp" : {
            "$gt" : ISODate("2015-01-01T00:00:00Z"),
            "$lt" : ISODate("2015-02-011T00:00:00Z")
    },
    "itemId" : "5"
}
40
Owumaro

L'objectif principal du aggregation framework est de faciliter la requête d'un grand nombre d'entrées et de générer un faible nombre de résultats qui ont de la valeur pour vous.

Comme vous l'avez dit, vous pouvez également utiliser plusieurs requêtes find, mais n'oubliez pas que vous ne pouvez pas créer de nouveaux champs avec des requêtes find. En revanche, le $group stage vous permet de définir vos nouveaux champs.

Si vous souhaitez bénéficier des fonctionnalités de aggregation framework, vous devrez probablement exécuter un find initial (ou en chaîner plusieurs), extraire ces informations et les manipuler davantage avec un langage de programmation.

Le aggregation pipeline peut sembler prendre plus de temps, mais au moins vous savez que vous n'avez qu'à prendre en compte les performances d'un seul système - le moteur MongoDB.

Alors que, lorsqu'il s'agit de manipuler les données renvoyées par une requête find, vous devrez probablement manipuler davantage les données avec un langage de programmation, augmentant ainsi la complexité en fonction des subtilités du langage de programmation de votre choix.

24
vladzam

Avez-vous essayé d'expliquer () à vos requêtes de recherche? Cela vous donnera une bonne idée du temps que prendra exactement la requête find (). Vous pouvez faire la même chose pour $ match avec $ expliquer et voir s'il y a une différence dans l'accès à l'index et d'autres paramètres.

De plus, la partie $ group du cadre d'agrégation n'utilise pas l'indexation, elle doit donc traiter tous les enregistrements renvoyés par l'étape de correspondance $ du cadre d'agrégation. Donc, pour mieux comprendre le fonctionnement de votre requête, voyez l'ensemble de résultats qu'elle retourne et si elle tient en mémoire pour être traitée par MongoDB.

7
harshad