1

In one of my views for the staff, I show the last 10 registrars on my site and some of their activity like so:

recentlyjoined = User.objects.order_by('-date_joined').annotate(post_count=Count('post', distinct=True),
                                                                    text_count=Count('text', distinct=True),
                                                                    pdf_count=Count('pdf', distinct=True),
                                                                    discussion_count=Count('discussion', distinct=True))[0:10]

And in my template I do

{% for applicant in recentlyjoined %}
{{ applicant.post_count }}
{% endfor %}

for all the annotations above.

When I call this site, it takes VERY long to load, sometimes I even get a timeout error. I narrowed it down to this annotations. Whats wrong? Why does this improve so bad? And how can I fix it?

(And in case it matters: In my sandbox database I have only 15 users, but one of them has like 5000 posts. So its not exactly big data to handle.)

1 Answer 1

1

Hello I won't answer your question straight away but since you suspect that the query is not slow you can rule it out.

  1. Enable query logging using the following config in your project's settings.py LOGGING configuration:
        'django.db.backends': {
            'level': 'DEBUG',
            'handlers': ['console'],
            'propagate': False
        }

resource: https://docs.djangoproject.com/en/3.1/topics/logging/#django-db-backends

this will log each query executed and the time it takes

  1. Another option is to enable a slow query log on your database but the above is simpler.

  2. If it appears that some query is slow you can get further details by copying the query and analysing the cost and the operations happening using buildin query plan analysis tools shiped with your database ie explain analyze for postgres.

  3. If it's not db query related you can profile your app with django debug toolbar or django silk

  4. Above all before all the above check that you didn't leave the debaugger on, stopped at some breakpoint.

Sign up to request clarification or add additional context in comments.

4 Comments

logging shows 7 seconds to perform the request... annotate() seems to perform very bad. now I try to solve it with functions on the class... but I run in circular import problems now...
to get rid of circular imports you can do the import in your function but I wouldn't recommend doing aggregates in code just optimize your query. In the long run it is always more expensive to do aggregates on your server rather than in your database. Please stick to using a database query(ies) for the job. Do think of memoryallocation / garbage collection transfering data, trips to the database, database connections if not using a connection pool like pgbouncer e.t.c
what's the actual query produced?
if you run you copy paste your query to the database how much does timed query take ie(in postgres using \timing). Are there any seq scans in explain analyze?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.