Optimiser les requêtes Django ORM
L'ORM de Django facilite le travail avec la base de données. Mais il cache un danger. Si vous récupérez mal les objets liés, vous créez le problème de la requête N+1.
Cela signifie que si vous récupérez 100 articles, votre application pourrait exécuter 101 requêtes. Cela ralentit considérablement votre application.
Utilisez ces deux outils pour corriger cela :
- select_related
Utilisez ceci pour ForeignKey et OneToOneField.
Il utilise une jointure SQL (SQL JOIN). Il récupère les données liées en une seule requête.
- Exemple : un Post a un seul Author.
- Méthode naïve : 101 requêtes pour 100 posts.
- Méthode optimisée : 1 requête en utilisant .select_related("author").
- prefetch_related
Utilisez ceci pour ManyToManyField et les ForeignKeys inverses.
Il exécute des requêtes distinctes et les joint en Python.
- Exemple : un Post a plusieurs Tags.
- Méthode naïve : 1 requête pour les posts + 1 requête pour les tags de chaque post.
- Méthode optimisée : 2 requêtes au total en utilisant .prefetch_related("tags").
Conseils de pro :
- Utilisez l'objet Prefetch pour filtrer les données liées avant qu'elles n'atteignent votre boucle.
- Chaînez-les. Vous pouvez utiliser les deux dans un même queryset pour récupérer les auteurs et les tags en même temps.
- Évitez d'appeler .filter() sur une relation préchargée à l'intérieur d'une boucle. Cela contourne le cache et sollicite à nouveau la base de données.
- Utilisez .only() avec select_related pour ne récupérer que les colonnes dont vous avez besoin.
Résumé :
- ForeignKey / OneToOne : Utilisez select_related.
- ManyToMany / ForeignKey inverse : Utilisez prefetch_related.
Vérifiez le nombre de vos requêtes avec django-debug-toolbar pour détecter ces problèmes rapidement.