2010-11-06 7 views
6

Certains profils montrent que le rendu de modèle est le coupable. (J'essaie sur une page avec seulement des requêtes en cache.) Mais encore, le modèle est très simple. La partie la plus complexe est une boucle imbriquée qui s'exécute 10 fois, mais si tout se passe bien, la boucle imbriquée ne s'exécute pas car elle est mise en cache. (Comme dans mes tests)django est très lent

qui est

{% for p in posts %} 
--{{p.by.username}} 
--{{p.text}} 
{% cache 600 p p.timestamp %} 
    {% for img in p.images.all %} 
     --{{img.path}} 
    {% endfor %} 
{% endcache %} 
{% endfor %} 

Je reçois 80 ~ req/s sur le dev. serveur pour cette page. (J'ai trouvé que je peux multiplier ce nombre par 3 dans le déploiement de production) Pour une comparaison, j'obtiens 1000req/s pour un modèle trivial qui ne contient qu'une courte chaîne statique.

Est-ce un problème connu? Comment puis-je corriger/éviter cela?

+0

Qu'est-ce qui est «lent»? –

+0

80 req/s est lent. parce que je ne fais rien si ce n'est pas un couple de memcache. – oscar

+0

Pas une réponse, mais plutôt une suggestion. Avez-vous essayé de la mise en cache comme ici: http://djangosnippets.org/snippets/507/ –

Répondre

2

(Apparemment, je ne suis pas « karmique » assez pour écrire des commentaires encore, ou je posterais cela comme un commentaire plutôt qu'une réponse)

Pouvez-vous préciser ce que vous entendez par « que les requêtes mises en cache »? En dehors de cela, il me semble que votre problème pourrait être que vous frappez votre base de données beaucoup pendant le rendu de modèle.

{% for p in posts %} 
--{{p.by.username}} {# 1 #} 
--{{p.text}} 
{% cache 600 p p.timestamp %} 
    {% for img in p.images.all %} {# 2 #} 
     --{{img.path}} 
    {% endfor %} 
{% endcache %} 
{% endfor %} 

Vous fournissez des "publications" à votre modèle; c'est une requête, que vous avez dit a 100 résultats.

Pour chaque itération sur les publications, vous devez alors accéder à la base de données au {# 1 #} pour obtenir p.by, que je suppose être un ForeignKey pour un utilisateur auth.User. En plus de cela, avec un cache invalide (première exécution), vous retournez à {# 2 #} pour obtenir la liste des images de ce message. Donc, pour 100 articles, vous frappez la base de données 201 fois par demande pour une exécution initiale, et 101 avec un cache rempli pour la boucle d'images.

Essayez d'utiliser select_related avec votre requête de posts pour extraire ces résultats supplémentaires dans une requête, si possible. Quelque chose comme posts = Post.objects.select_related('by', 'images').filter(...) pourrait faire l'affaire, même si je sais select_related a des limites quand il s'agit de renverser les clés étrangères et les champs m2m (il pourrait ne pas fonctionner pour les images, en fonction de la structure de vos modèles).

+0

J'utilise déjà select_related lorsque la requête n'est pas mise en cache, mais comme je l'ai dit, dans ce cas, je ne tire que les résultats de memcached. - Alors oui, la barre d'outils de débogage montre 0 requête exécutée. – oscar

+0

Aussi, j'ai dit qu'il a 10 résultats, pas 100. – oscar

+0

C'était dans un commentaire que vous avez dit "100 boucles"; J'ai pris le 10 que vous avez mentionné dans votre question pour signifier que la boucle d'images intérieure court dix fois pour chaque poste. Désolé si j'ai mal compris. – eternicode