2010-10-08 5 views
1

Je dois récupérer 5 objets qui correspondent à un certain critère complexe, et je ne peux pas/ne veux pas passer ce critère à la clause WHERE (filtre dans django), donc j'ai besoin de parcourir les résultats, en testant chaque enregistrer pour les critères jusqu'à ce que je reçois mes 5 objets, après cela, je veux jeter l'ensemble de la requête et ne jamais le revoir.Comment parcourir correctement un énorme QuerySet dans django?

Dans la plupart des cas, les enregistrements dont j'ai besoin seront au début de l'ensemble de requêtes, dans le pire des cas, ils seront à leur fin. La table est énorme et j'ai seulement besoin de 5 enregistrements. Donc ma question est: Comment puis-je itérer sur un ensemble de requêtes sans avoir django pour mettre en cache les résultats? Cela doit être fait de telle sorte que ni le moteur sql/django ne stocke/cache les résultats n'importe où.

Répondre

1

Pourquoi vous inquiétez-vous de la mise en cache? Laissez Django ou mysql faire ce qu'ils font.

Si vous êtes penchés dessus. Vous pouvez désactiver la mise en cache pour Django. C'est une chose assez simple à faire dans settings.py pour votre projet.

Pour Mysql, vous devez exécuter certains querie (s) pour désactiver le cache de requêtes -

Essayez d'utiliser l'option SQL_NO_CACHE dans votre requête. Comme si

SELECT SQL_NO_CACHE * FROM TABLE 

Cela arrêtera la mise en cache des résultats MySQL, mais sachez que d'autres caches OS et disque peuvent également influer sur les performances. Ceux-ci sont plus difficiles à contourner.

Un problème avec cette méthode est qu'il semble seulement empêcher le résultat de votre requête d'être mis en cache. Toutefois, si vous interrogez une base de données activement utilisée avec la requête que vous souhaitez tester, les autres clients peuvent mettre en cache votre requête, ce qui affecte vos résultats. Je continue à chercher des moyens autour de ceci, éditerai cet article si j'en trouve un.

OU

Vous pouvez également faire RESET QUERY CACHE

OU

FLUSH QUERY CACHE 

Bien qu'un point à noter est que je suggère de laisser la Mysql gérer la clause WHERE comme il l'a couche d'optimisation de requête qui serait très efficace si vous avez les bons champs indexés. Obtenir tous les résultats & vous faites ce que la clause WHERE peut vous ralentir en fonction de la taille de l'ensemble de la requête. Juste quelque chose à penser. Je suppose que l'analyse comparative appropriée devrait vous montrer le chemin.

+0

savez-vous comment désactiver le cache dans postgresql? (Forcez-le à utiliser un curseur) –

+0

Vous pouvez vous débarrasser des caches de PostgreSQL dans shared_buffers en redémarrant le serveur PostgreSQL. Je ne sais pas s'il y a un moyen plus pratique. Alternativement, il suffit de définir un shared_buffers vraiment minime qui est juste suffisant pour vos connexions, donc il n'y a pas beaucoup de place pour les données en cache. –

+0

@Thiado a ajouté plus de matos yo ma réponse. J'espère que cela t'aides. Une raison pour laquelle vous ne voulez pas de cache? Des tests de performance sont en cours? –

0

Django n'a pas de cache global (voir ticket # 14). Cela signifie que tant que vous ne gardez rien, les données seront supprimées et ne seront plus mises en cache. À ce stade, le garbage collector supprimera l'allocation de mémoire lors du prochain nettoyage. Par conséquent, un code tel que:

my_objects = [obj for obj in MyModel.objects.all() if my_complex_condition(obj)] 

La seule django cache ferait ici est dans le cas particulier ci-dessus, et après cette ligne toute référence au cache serait disparu. Notez que si Django n'avait aucun cache, la mémoire se remplirait toujours de la même manière, et le GC collecterait les lignes individuellement de toute façon.

+0

Ceci n'est pas vrai.Si vous exécutez réellement ce code, vous verrez l'empreinte mémoire grimper et grimper et grimper – priestc

Questions connexes