7
votes

Comment accélérer l'itération de grands ensembles de données à Django

J'ai une requête d'environ 1500 enregistrements d'une requête Django Orm. J'ai utilisé les méthodes Select_Related () et uniquement () pour vous assurer que la requête est serrée. J'ai également utilisé la connexion.Quiseries pour vous assurer qu'il n'y a qu'une seule requête. C'est-à-dire que je me suis assuré qu'aucune requête supplémentaire ne s'appelle sur chaque itération.

Lorsque j'exécute la requête coupée et coller de la connexion.Qui, il fonctionne en 0.02 secondes. Cependant, il faut sept secondes pour itérer ces dossiers et ne rien faire avec eux (Pass).

Que puis-je faire pour accélérer cela? Qu'est-ce qui cause cette lenteur?


2 commentaires

Vous devez inclure plus de détails sur vos modèles et la requête!


Vous devriez également écrire Django <- de cette façon :) il était un guitariste, pas un DJ


4 Réponses :


16
votes

Un querySet peut être assez lourd quand il est plein d'objets modèles. Dans des situations similaires, j'ai utilisé la méthode .values ​​sur le QuerySet pour spécifier les propriétés dont j'ai besoin en tant que liste de dictionnaires, ce qui peut être beaucoup plus rapide à itérer. http://docs.djangoproject.com/fr/1.3/ref/models/querysets / # Liste de valeurs


3 commentaires

Tu avais raison. Il s'avère que l'instanciation des objets de modèle sur chaque itération a entraîné beaucoup de frais généraux. L'utilisation de la méthode de valeurs a pris l'itération de l'ensemble de sept secondes, à seulement quelques millisecondes.


Impressionnant. Heureux que j'ai pu aider.


J'ai remarqué une augmentation énorme des performances avec cela! J'étais itération d'un querySet de 110000 articles, qui a pris près de 70 secondes à compléter. Itération de la même valeur_List a pris 5 secondes!



2
votes

1500 enregistrements est loin d'être un grand jeu de données et sept secondes est vraiment trop. Vous trouverez probablement un problème dans vos modèles, vous pouvez facilement le vérifier en obtenant (comme le dit Brandon) la requête Valeurs (), puis créez explicitement l'objet 1500 en itérant le dictionnaire. Il suffit de convertir les valeursQuiseryset dans une liste avant la construction pour facturer la connexion DB.


0 commentaires

2
votes

Comment êtes-vous itération sur chaque élément: xxx

régulier pour la boucle sur chaque xxx

ou à l'aide du requérant itérateur xxx

Selon le doc, le itérateur () peut améliorer les performances. Il en va de même en boucle une très grande liste de python ou dictionnaires, il est préférable d'utiliser iteritems () .


2 commentaires

Je ne sais pas si cela fonctionnerait, car la plupart du temps, l'itération est effectuée dans le modèle et je ne suis pas sûr que nous ayons le .itéroator () là.


Je l'ai vérifié et ça marche réellement. Accélérez beaucoup la boucle. De 0: 00: 45.550635 à 0: 00: 09.761178, donc au moins 4 fois plus vite !!!



1
votes

Est-ce que votre modèle méta est-ce que votre modèle est "commander par" un champ stocké dans une autre table associée? Si tel est le cas, votre tentative d'itération peut déclencher 1 500 requêtes alors que Django s'épuise et saisit ce champ pour chaque élément, puis les trie. Nous montrant que votre code nous aiderait à démêler le problème!


0 commentaires