Prompt
The N+1 query problem is one of the most common performance bottlenecks in Django applications. This occurs when you retrieve a list of objects and then access related objects for each one individually, causing an additional database query for each parent object.
To prevent N+1 queries, follow these strategies in order of complexity:
- Start with
FETCH_PEERSmode: This is the simplest approach and should be your first consideration when optimizing queries.
from django.db.models import fetch_mode, FETCH_PEERS
# Apply to a specific code block
with fetch_mode(FETCH_PEERS):
articles = Article.objects.all()
for article in articles:
print(article.reporter) # Fetches all reporters in one query
# Or set globally in an AppConfig
from django.apps import AppConfig
from django.db.models import set_default_fetch_mode, FETCH_PEERS
class MyAppConfig(AppConfig):
name = 'myapp'
def ready(self):
set_default_fetch_mode(FETCH_PEERS)
- Use
select_related()for forward ForeignKey relationships: ```pythonInstead of this (causes N+1 queries):
for article in Article.objects.all(): print(article.reporter.name)
Do this (single query):
for article in Article.objects.select_related(‘reporter’): print(article.reporter.name)
3. **Use `prefetch_related()` for reverse or many-to-many relationships**:
```python
# Instead of this (causes N+1 queries):
for reporter in Reporter.objects.all():
print([article.headline for article in reporter.article_set.all()])
# Do this (two queries):
for reporter in Reporter.objects.prefetch_related('article_set'):
print([article.headline for article in reporter.article_set.all()])
- For complex cases, combine approaches:
queryset = Book.objects.select_related('publisher').prefetch_related('authors') - Use the
RAISEfetch mode during development to catch accidental N+1 queries:with fetch_mode(RAISE): # Code that should not trigger additional queries render(request, "template.html", context)
Remember that fetching too much data can also be inefficient. Choose the appropriate strategy based on your specific access patterns.