How to speed up Django QuerySets

Despite the temptation of buying new servers and adding CPU and RAM – you need to do what you can with the code first. I am exploring and cataloguing these methods to speed up Django QuerySets before server scaling.

The general idea is simple – use more QuerySet methods instead of Python methods to avoid evaluation.

1. Use exists()

Add .exists to your QuerySet if you need to find if the QuerySet is empty or not. Most likely, if you are interested in this kind of article – you already have enough database records for this advice to be notable. If your DB is small, it won’t change much. But it would be a good practice to start using .exists() as well as .count() (say, instead of len(list(QuerySet))).

2. Use .filter() and .exclude() more

There QuerySet methods don’t access the QuerySet itself before the iteration – they are executed in the DB, therefore they are faster.

Basically, instead of:

for profile in Profile.objects.all():
    if not profile.is_blocked.filter(user__name='Katerina'):
        return profile

Do this:

profiles = Profile.objects.exclude(is_blocked__user__name='Katerina')
return profiles.first()  # returns None if pool is empty

# you can also do this
if profiles.exists():
    # do what you need

3. Do not use list()

Say, instead of list(QuerySet)[0] use QuerySet.first(). Or QuerySet.last(). You hardly ever need to do list() – find a way to do it with QuerySet methods. In most cased you may need a for cycle or a generator to further do something with the data, but that’s about that.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.