Skip to main content

Command Palette

Search for a command to run...

Understanding select_related vs prefetch_related in Django

Updated
3 min read
Understanding select_related vs prefetch_related in Django

Another question I was asked in my technical interview was the difference between select_related and prefetch_related. I’m going to talk about it in this article so we can all learn from it,

When working with Django’s ORM, one of the most common performance issues developers run into is the N+1 query problem. This happens when each object in a queryset triggers its own database query to fetch related data. Thankfully, Django gives us two powerful tools to optimize queries: select_related and prefetch_related.

Both methods help reduce database hits, but they work differently under the hood. Let’s break it down.


What is select_related?

How it works

  • Used for single-valued relationships: ForeignKey and OneToOneField.

  • Performs an SQL JOIN to fetch related objects in a single query.

  • Best when you know you’ll need related data for each object.

Example

class Author(models.Model):
    name = models.CharField(max_length=100)

class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.ForeignKey(Author, on_delete=models.CASCADE)

# Without select_related
books = Book.objects.all()
for book in books:
    print(book.author.name)  # Each loop triggers a new query!

# With select_related
books = Book.objects.select_related("author")
for book in books:
    print(book.author.name)  # Single JOIN query!

👉 Result: Faster queries with less database load when dealing with one-to-one or many-to-one relationships.


What is prefetch_related?

How it works

  • Used for multi-valued relationships: ManyToManyField and reverse ForeignKey.

  • Executes separate queries for related objects, then merges them in Python.

  • Ideal for cases where multiple related rows need to be fetched.

Example

class Author(models.Model):
    name = models.CharField(max_length=100)

class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.ForeignKey(Author, related_name="books", on_delete=models.CASCADE)

# Without prefetch_related
authors = Author.objects.all()
for author in authors:
    for book in author.books.all():
        print(book.title)  # Triggers a query for each author!

# With prefetch_related
authors = Author.objects.prefetch_related("books")
for author in authors:
    for book in author.books.all():
        print(book.title)  # Just 2 queries total!

👉 Result: Fewer queries overall when fetching multiple related objects.


Key Differences Between select_related and prefetch_related

Featureselect_relatedprefetch_related
Works withForeignKey, OneToOneFieldManyToManyField, reverse ForeignKey
Query typeSQL JOIN (single query)Multiple queries + Python join
Best forSingle-related objectsMulti-related objects
Performance impactReduces queries for one-to-one/many-to-one lookupsReduces queries for many-to-many/one-to-many lookups

Rule of Thumb

  • Use select_related when fetching single-related objects (ForeignKey, OneToOne).

  • Use prefetch_related when fetching collections of related objects (ManyToMany, reverse ForeignKey).

By using these tools wisely, you can drastically improve your Django application’s performance and keep your database queries efficient.


✅ Pro Tip: You can even combine them:

Book.objects.select_related("author").prefetch_related("reviews")

This way, you optimize both single-valued and multi-valued relationships in one go!


Final Thoughts

Understanding the difference between select_related and prefetch_related is essential for writing efficient Django queries. select_related leverages SQL joins for single-related lookups, while prefetch_related handles multi-related lookups by batching queries and joining in Python.

Mastering these techniques will save you from performance bottlenecks and keep your Django apps running smoothly.

More from this blog

F

Freelance Full-Stack Developer | Django + React | Shopify, WordPress & Automation | I Build Web Experiences That Convert

95 posts

Freelance Full-Stack Developer | Django + React | Shopify, WordPress & Automation | I Build Web Experiences That Convert