Django: alternative to using annotations (Count ()) for speed

There are two models with a one-to-one relationship, A → {B}. I count how many records A I have with the same B after using filter (). Then I need to extract the top X-records A in terms of most of the related records B.

Current code:

class A(models.Model): code = models.IntegerField() ... class B(models.Model): a = models.ForeignKey(A) ... data = B.objects.all().filter(...) top = data.values('a',...).annotate(n=Count('a')).distinct().order_by('-n')[:X]; 

I have records of ~ 300 KB, and with my laptop it takes ~ 2 s for a single request. I split the request into parts and timed it, and it seems that the annotation () seems to be the main bottleneck.

Is there a way to make this faster with Django?

+6
source share
1 answer

You must add .select_related('a') before annotate in the query set. This will force django to join the models before reading them.

https://docs.djangoproject.com/en/1.9/ref/models/querysets/#select-related

0
source

All Articles