Django ORM Performance Booster Tips

MSI Shafik
Nov 3 · 2 min read

There are several ways to boost up the Django’s ORM performance. I am going to point out some of these after studying about this topic.

1. Using cache property of Django:

queryset = Post.objects.all() # will not hit the database
print(queryset) # will hit the database
print(queryset[:100]) # will hit the database
print(queryset[101:200] # will hit the database

We can use django’s cache property for reducing database hit on every line of code execution.

queryset = Post.objects.all() # will not hit the database
bool(queryset) # queryset will be evaluated
and results will be cached.
# Now queryset will use the cache data.
print(queryset) # will not hit the database
print(queryset[:100]) # will not hit the database
print(queryset[101:200] # will not hit the databaseCount

2. Using select_related() and prefetch_related():

select_related() : Foreign key, one-to-one relationship query without doing hit on the database again and again. To know details: Click Here.

prefetch_related():Many-to-many, many-to-one relationship without doing hit on the database again and again. To know details: Click Here.

3. Providing index to fields in database models & provide default ordering:

3. Using list values of queryset objects instead of using Subquery() if possible:

authors = Author.objects.all()
books = Books.objects.filter(author__in=authors)

In this scenario, it will hit database 3 times,

First time, when author__in = authors,

Second time, when it will get filter() method,

Third time, when executing books queryset.

Instead of this, list can be use for optimizing the performance:

authors = Author.objects.values_list('id', flat=True)  # will return a flat value list of author idbooks = Books.objects.filter(author_id__in=authors)

4. Using iterator() for large queryset when no cache query data is needed :

Use of iterator() method is very effective for large queryset if cache data is not needed for further code execution.

# will Save memory but not caching anything
# only for single execution of large queryset
for book in Books.objects.iterator():
... something....

5. Using defer() or only(), values() or values_list() for avoiding unnecessary query data:

defer()- click here , only()- click here

6. Avoiding database queries in loop or work on database rather than in python:

Avoiding database queries in loop, rather than use different ORM method such as —aggregate, annotate, Max, Min, Count and so on.

max_price = 0for book in Book.objects.all():    if book.price>max_price:         max_price = book.price

Instead of doing that type of query, do this-

max_price =  Book.objects.all().aggregate(Max('price'))['price__max']

[Thanks for being with me. If you find any inconsistency please let me know … :) ]

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade