אופטימיזציה של שאילתות Django ORM

Django ORM הופך את העבודה עם מסדי נתונים לקלה. אך הוא מסתיר סכנה. אם שולפים אובייקטים קשורים בצורה לא טובה, אתם יוצרים את בעיית ה-N+1 query.

זה אומר שאם תשלפו 100 פוסטים, האפליקציה שלכם עלולה להריץ 101 שאילתות. זה מאט את האפליקציה שלכם עד לעצירה מוחלטת.

השתמשו בשני הכלים האלו כדי לתקן זאת:

  1. select_related

השתמשו בזה עבור ForeignKey ו-OneToOneField.

זה משתמש ב-SQL JOIN. זה שולף את הנתונים הקשורים בשאילתה אחת.

  • דוגמה: ל-Post יש Author אחד.
  • הדרך הנאיבית: 101 שאילתות עבור 100 פוסטים.
  • הדרך האופטימלית: שאילתה אחת באמצעות .select_related("author").
  1. 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 כדי לזהות בעיות כאלו בשלב מוקדם.

מקור: https://dev.to/fhva29/optimizing-django-orm-queries-a-practical-guide-to-selectrelated-and-prefetchrelated-1gpl