تبدیل n+1 عدد query به 3 query

این یک مثال واقعی از بهبود یک پروژه است. query اولیه به شکل زیر بود:

با ابزار django debug toolbar تعداد query های این تکه کد را مرور کردم و جاهایی که به سرور query زده میشود به این شکل است:

  1. در خط Branch.objects.get(name__iexact=”bss”).office_set.all() یک query به دیتابیس زده میشود.

2. در خط for el in bss_branch: یک query به دیتابیس زده می شود.

3. در خط for svc in el.services.all(): یک query به دیتابیس زده میشود. یعنی اگر در bss_branch تعداد N المان وجود داشته باشد به ازای هر کدام یک query در این قسمت زده خواهد شد.

یعنی برای هر el که تعداد آن به اندازه bss_branch هست یک query جدید داریم

بنا براین در کد بالا یک query زده شده و branch ها استخراج شده (در قسمت 1) که ترجمه آن:

در قسمت دوم یک query زده شده و office های آن branch استخراج شده:

در قسمت سوم به ازای هر کدام از office ها یک query زده شده و service های آن استخراج شده به عنوان مثال یکیش رو آوردم:

پس در مجموع N+1 درخواست دیتابیس query زدن شد.

حالا اینو بهینه میکنیم به کد زیر:

در این نمونه کد query های زیر را داریم:

  1. در خط bss_branch = Branch.objects.get(name__iexact=”bss”).office_set.prefetch_related(‘services’) یک query به دیتابیس داریم.
  2. در خط for el in bss_branch: یک query زده شده و office های branch را استخراج کرده.
  3. دوباره در همان خط یک query زده شده و service های تمامی office ها یک جا استخراج شده در این قسمت دیگر N بار query زده نشده

query قسمت 1

query قسمت 2

query قسمت 3

همانطور که توی کد بالا میبینید توی خط آخر تمامی query ها ادغام شده اند

بنابراین N+1 دستور query به 3 query تبدیل شد

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *