10
votes

Python + Mongodb - Itération du curseur trop lent

Je travaille réellement dans un projet de moteur de recherche.
Nous travaillons avec Python + MongoDB.
J'ai le problème suivant:

J'ai un curseur Pymongo après avoir excécutant une commande de recherche () à la DB Mongo.
Le curseur Pymongo a environ 20 000 résultats.

J'ai remarqué que l'itération sur le curseur de Pymongo est vraiment lente par rapport à une itération normale par exemple une liste de la même taille.

J'ai fait un peu de référence:

-itération sur une liste de 20k chaînes: 0.001492 secondes
-éralisation sur un curseur de Pymongo avec des résultats 20K: 1.445343 secondes

La différence est vraiment beaucoup. Peut-être pas de problème avec ces quantités de résultats, mais si j'ai des millons de résultats, le temps serait inacceptable.

Quelqu'un a-t-il une idée de pourquoi les curseurs Pymongo sont trop lents à itérer?
Une idée de comment puis-je itération du curseur en moins de temps?

Quelques informations supplémentaires:

  • Python V2.6
  • PymonGo V1.9
  • mongodub v1.6 32 bits

4 commentaires

Pouvez-vous modifier la logique de votre application - par exemple en utilisant .skip () et .limit () - afin que vous ne retrouviez pas de tels ensembles de résultats?


En fait, 20k est un très petit% du montant total des documents. Je pense que ce n'est pas une solution évolutive, car je m'attends à avoir beaucoup plus de résultats que 20k. Merci de n'importe quelle manière =).


Sont chacun de vos résultats des cordes nues?


Non, j'ai un documentation similaire à: {"quelque chose": "string", "autre": [{"clé", "valeur"}, {"key2": "valeur2"}, ...], "quelque chose_more ": Integer}. Toute façon, j'ai récemment essayé avec une collection de documents de chaînes nus, reliez ce problème: {"quelque chose": "string"} et la différence de temps dans l'itération est la même. : S


4 Réponses :


12
votes

N'oubliez pas que le pilote Pymongo ne vous donne pas de résultats de 20k à la fois. Il effectue des appels réseau vers le backend Mongodb pour plus d'articles au fur et à mesure de votre itération. Bien sûr, il ne sera pas aussi rapide qu'une liste des chaînes. Cependant, je suggère d'essayer d'ajuster le curseur Batch_size comme indiqué dans le API DOCS :


7 commentaires

C'était une bonne réponse. J'ai fait un test. Voir les résultats: curseur plus de 800 000 documents. BATCH_SIZE = 1 en 44Secondes, Batch_Size = 100 en 8Secondes, Batch_Size = 1000 en 7.29Seconde, Batch_Size = Quantité par défaut en 12SECONDS. Il semble être important dans le temps d'itération final. Merci!


J'ai aussi des avis que cela dépend bien sûr de la quantité de données que vous transfètez entre Mongo et le script. C'est pourquoi j'ai changé ma requête Ajout de restrictions aux clés dont je n'ai pas besoin dans l'itération, comme: .Find ({}, {"Key1": 0, "Key3": 0}). Cela a beaucoup diminué le temps.


Les deux éléments ont un sens - les contrôles par lots combien d'articles sont envoyés sur chaque extraction de MongoDB. Limiter certainement les champs que vous revenez uniquement à ceux que vous utilisez réduiront le trafic réseau nécessaire.


@Brendan, que peut-il arriver si j'essaie d'utiliser le pilote de Mongo C ++ à la place du Python? Pensez-vous que cela peut travailler plus vite? Ou le problème est-il dans la façon dont Mongo fonctionne et non son conducteur? Merci!


Pas particulièrement - c'est la nature de l'expédition de documents 20K sur le réseau.


@Brendan. J'ai fait un test à l'aide du pilote C ++ au lieu de la Python, et la performance était 3 fois plus rapide avec la même requête. Je pense que c'est quelque chose d'important de prendre en compte. Merci!


Le lien dans la réponse ne fonctionne pas ..Veuillez le mettre à jour.



-3
votes

Vous ne fournissez aucune information sur la taille du document global. Fixer une telle quantité de document nécessite à la fois le trafic réseau et l'IO sur le serveur de base de données.

La performance est maintenue "mauvaise" même dans l'état "chaud" avec des caches chaudes? Vous pouvez utiliser "Mongosniff" afin d'inspecter l'activité "Wire" et des outils système tels que "iostat" pour surveiller l'activité de disque sur le serveur. En outre, "Mongostat" donne un tas d'informations précieuses ".


4 commentaires

En dehors de cela: chaque idiot essayant d'effectuer une baisse en série devrait lire ceci: Meta .stackexchange.com / Questions / 28756 / Serial-Downvoting-Vic Tim


Si vous lisez le lien que vous avez posté, vous saurez que vous n'avez pas besoin de vous inquiéter. Les bowvotes seront suffisamment annulés.


Peut-être que les gens cessaient de vous baisser si vous cessez d'appeler tout le monde "idiot". S'il vous plaît attention à vos manières. Je vous ai référé au FAQ plus d'une fois pour lire la section sur un comportement acceptable; Le nom appelant ne fait pas partie de ce comportement.


Ne vous inquiétez pas pour la vengeance descendante, le système s'en occupe facilement. Toutefois, craignez-vous d'être abrasif dans vos réponses et vos commentaires. Essayez de le garder professionnel, mkay?



1
votes

La taille du curseur par défaut est de 4 Mo et le maximum qu'il peut aller à 16 Mo. Vous pouvez essayer d'augmenter la taille de votre curseur jusqu'à ce que cette limite soit atteinte et voyez si vous obtenez une amélioration, mais cela dépend également de ce que votre réseau peut gérer.


0 commentaires

15
votes

est votre installation de PymonGo à l'aide de l'inclus c Extensions C ? XXX

J'ai passé la majeure partie de la semaine dernière à essayer de déboguer une requête de taille moyenne et un traitement correspondant qui a pris 20 secondes à exécuter. Une fois que les extensions C ont été installées, tout le même processus a pris environ une seconde.

Pour installer les extensions C dans Debian, installez les en-têtes de développement Python avant d'exécuter une installation facile. Dans mon cas, j'ai aussi dû supprimer l'ancienne version de Pymongo. Notez que cela compilera un binaire de C, vous avez donc besoin de tous les outils habituels. (GCC, etc.) xxx


2 commentaires

Cela a définitivement fasturé ma performance. J'ai eu une requête qui a pris 5 sectes, prenant maintenant 0,01! J'ai ajouté les étapes pour l'installation sur Ubuntu


Je sais que c'est très vieux, mais comment pouvez-vous l'installer sur le dernier système d'exploitation X?