אופטימיזציה של שאילתות Django ORM
Django ORM הופך את העבודה עם מסדי נתונים לקלה. אך הוא מסתיר סכנה. אם שולפים אובייקטים קשורים בצורה לא טובה, אתם יוצרים את בעיית ה-N+1 query.
זה אומר שאם תשלפו 100 פוסטים, האפליקציה שלכם עלולה להריץ 101 שאילתות. זה מאט את האפליקציה שלכם עד לעצירה מוחלטת.
השתמשו בשני הכלים האלו כדי לתקן זאת:
select_related
השתמשו בזה עבור ForeignKey ו-OneToOneField.
זה משתמש ב-SQL JOIN. זה שולף את הנתונים הקשורים בשאילתה אחת.
- דוגמה: ל-Post יש Author אחד.
- הדרך הנאיבית: 101 שאילתות עבור 100 פוסטים.
- הדרך האופטימלית: שאילתה אחת באמצעות
.select_related("author").
prefetch_related
השתמשו בזה עבור ManyToManyField ו-reverse ForeignKeys.
זה מריץ שאילתות נפרדות ומחבר אותן ב-Python.
- דוגמה: ל-Post יש הרבה Tags.
- הדרך הנאיבית: שאילתה אחת עבור הפוסטים + שאילתה אחת עבור ה-tags של כל פוסט בנפרד.
- הדרך האופטימלית: 2 שאילתות בסך הכל באמצעות
.prefetch_related("tags").
טיפים של מקצוענים:
- השתמשו באובייקט
Prefetchכדי לסנן נתונים קשורים לפני שהם מגיעים ללולאה שלכם. - שרשרו אותם יחד. ניתן להשתמש בשניהם ב-
querysetאחד כדי לקבל גם את ה-authors וגם את ה-tags בבת אחת. - הימנעו מקריאה ל-
.filter()על קשר שעברprefetchבתוך לולאה. זה עוקף את ה-cache ופונה למסד הנתונים שוב. - השתמשו ב-
.only()יחד עםselect_relatedכדי לשלוף רק את העמודות שאתם צריכים.
סיכום:
ForeignKey/OneToOne: השתמשו ב-select_related.ManyToMany/Reverse FK: השתמשו ב-prefetch_related.
בדקו את כמות השאילתות שלכם באמצעות django-debug-toolbar כדי לזהות בעיות כאלו בשלב מוקדם.