Si vous lisez cet article, il est probable que vous rencontriez le problème N+1 dans le développement Django ou que vous ayez au moins une fois déjà été confronté à ce problème. À cause de cela, la vitesse de chargement de vos pages peut ralentir, et vous avez peut-être découvert les méthodes select_related
et prefetch_related
en cherchant des solutions.
Tout d'abord, bienvenue sur mon blog ! 🎉 En lisant cet article jusqu'à la fin, vous apprendrez certainement à résoudre efficacement le problème N+1.
Si vous n'êtes pas encore familiarisé avec le concept du problème N+1, je vous recommande de lire l'article ci-dessous en premier.
✅ Qu'est-ce que le problème N+1 dans Django ORM ? Pourquoi cela se produit-il ?
🔍 Deux méthodes pour résoudre le problème N+1 dans Django
Django ORM offre deux fonctionnalités, select_related
et prefetch_related
, pour résoudre le problème N+1. Cependant, ces deux fonctionnalités fonctionnent différemment, il est donc important de comprendre exactement quand utiliser chacune d'elles.
📌 Principe commun de select_related
et prefetch_related
Le principe commun fondamental de ces deux méthodes est que les champs nécessaires à la logique sont récupérés en une seule fois dans la base de données, afin d'utiliser efficacement les données récupérées par Django.
Par exemple, imaginez que vous alliez dans un grand supermarché pour acheter les ingrédients nécessaires à la préparation d'un gâteau, tels que de la farine, de la crème fouettée et des fruits, et que vous les achetiez tous en une seule fois. En rentrant chez vous pour cuisiner, tous les ingrédients sont prêts, vous pouvez donc commencer immédiatement la préparation.
Mais que se passerait-il si vous deviez aller acheter les ingrédients un par un ? Vous retourneriez du supermarché avec la farine, mais réaliseriez qu'il vous manque de la crème fouettée et devriez donc retourner au magasin, puis vous achèteriez la crème fouettée, mais il manquerait cette fois-ci des fruits, alors vous devirez encore aller au supermarché ?
Un tel processus ralentirait considérablement la cuisine. Dans Django ORM, select_related
et prefetch_related
aident à éviter cette récupération inefficace des données, en récupérant d'avance les données nécessaires avec une seule requête à la base de données, ce qui permet un traitement rapide.
✅ 1. select_related
– Chargement immédiat avec SQL JOIN
Utilisé pour les relations ForeignKey (1:N)
- Récupère les données en une seule requête grâce à SQL JOIN
- Aucune demande additionnelle à la base de données car les objets associés sont récupérés immédiatement
📌 Exemple d'utilisation de select_related
authors = Author.objects.select_related('post_set').all()
🧐 SQL exécuté lorsque select_related
n'est pas appliqué
SELECT * FROM author;
SELECT * FROM post WHERE author_id = 1;
SELECT * FROM post WHERE author_id = 2;
...
🚀 SQL exécuté lorsque select_related
est appliqué
SELECT * FROM author INNER JOIN post ON author.id = post.author_id;
✅ 2. prefetch_related
– Chargement préalable avec des requêtes individuelles
Utilisé pour les relations ManyToMany et Reverse ForeignKey
- Exécute des requêtes individuelles, puis Django optimise les données en Python pour les relier
- Puisqu'il n'utilise pas SQL JOIN, cela peut être plus favorable lors du traitement d'un grand volume de données
📌 Exemple d'utilisation de prefetch_related
authors = Author.objects.prefetch_related('post_set').all()
🧐 SQL exécuté après application de prefetch_related
SELECT * FROM author;
SELECT * FROM post WHERE author_id IN (1, 2, 3, 4, 5, ...);
🎯 Conclusion – En suivant ces étapes, vous résoudrez le problème N+1 !
Lorsque vous utilisez Django ORM, ignorer le problème N+1 peut gravement nuire à la performance. Cependant, en utilisant correctement select_related
et prefetch_related
, vous minimisez le nombre d'exécutions SQL et améliorez considérablement la vitesse de chargement des pages.
✅ Résumé
- Utiliser
select_related
pour les relations ForeignKey (1:N) - Utiliser
prefetch_related
pour des relations ManyToMany ou de reverse - Vérifiez toujours les SQL exécutées pour optimiser
- Si la vitesse d'exécution des requêtes ralentit, suspectez le problème N+1
📌 N'hésitez pas à lire les articles connexes !
✅ Qu'est-ce que le problème N+1 dans Django ORM ? Pourquoi cela se produit-il ?
Maintenant, essayez de résoudre le problème N+1 en utilisant select_related
et prefetch_related
! 🚀 Si vous ne comprenez pas bien ou si vous avez d'autres questions, n'hésitez pas à laisser un commentaire ou à poser une question. 😊
Add a New Comment