DEV Community

Cover image for Why Queryset.exists() is more efficient than Queryset.count()
Code Review Doctor
Code Review Doctor

Posted on • Updated on

Why Queryset.exists() is more efficient than Queryset.count()

During my career as a codebase review bot I've seen many variations of this anti-pattern:



import models 

queryset = models.Hound.objects.filter(is_asleep=True)


if queryset.count() > 0:
    return "run away!"
else:
    return "coast is clear"



Enter fullscreen mode Exit fullscreen mode

An experienced Django dev may chuckle at this misapplication of count(). I would never make that mistake! The thing is no dev is an island: over time devs change teams, inherit brownfield codebase that have accumulated tech debt, and will review code written by junior devs. It's therefore important to:

  • avoid the mistake
  • know how to effectively find and fix the mistake
  • know how to communicate what Django does to make exists quicker

At the end of the post I will show how to effortlessly find and fix this anti-pattern.

Efficiency

Comparing queryset.count() is less efficient than checking queryset.exists(). The above example is a harder to read and less efficient variations of the following:



import models 

queryset = models.Hound.objects.filter(pk=1)


if queryset.exists():
    return "run away!"
else:
    return "coast is clear"



Enter fullscreen mode Exit fullscreen mode

The Django docs tells us to use querySet.count() if you only want the count, and use queryset.exists() if you only want to find out if at least one result exists.

The reason for this advice is because queryset.count() performs an SQL operation that scans every row in the database table to calculate the sum. On the other hand queryset.exists() simply reads a single record in the most optimized way:

  • remove ordering
  • remove grouping
  • clear any dev-defined select_related and distinct from the queryset

Does your codebase misuse queryset.count?

Over time it's easy for tech debt to slip into your codebase. I can check that for you at django.doctor, or can review your GitHub PRs:

Alt Text

Or try out Django refactor challenges.

Top comments (0)