این 2 کد را در نظر بگیرید:
1 2 3 |
Service.objects.annotate( cnt_p=Count('provided_links'), cnt_c=Count('consumed_links') ).exclude(Q(cnt_p=0, cnt_c=0), st=2) |
و
1 2 3 |
Service.objects.exclude(st=2).annotate( cnt_p=Count('provided_links'), cnt_c=Count('consumed_links') ).exclude(cnt_p=0, cnt_c=0) |
با تبدیل اولی به دومی زمان این query از 450 میلی ثانیه به 45 میلی ثانیه کاهش پیدا کرد. چرا؟
دلیل این بود که فیلدهای این مدل همگی Index بودند اما این ایندکسها اعمال نمی شدند چونکه annotate باعث میشود که کل جدول اسکن شود و عملا ایندکسها بی فایده باشند بنابراین حداقل st=0 را به قبل از annotate انتقال دادیم و این باعث شد برای annotate که اتفاقا از WHERE استفاده میکند از ایندکس استفاده شود.