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.