claude-vault/knowledge/anti-patterns/n-plus-1-queries.md
2026-02-04 16:49:53 +01:00

58 lines
1.8 KiB
Markdown

# ANTI-PATTERN: N+1 Queries in Django ORM
## KONTEXT
Django/DRF API-Entwicklung, insbesondere bei Listen-Endpoints mit Related Objects.
## WAS IST PASSIERT?
```python
# SCHLECHT: N+1 Query Problem
def get_matches(request):
matches = Match.objects.filter(scenario_id=scenario_id)
return Response([{
'id': m.id,
'home_team': m.home_team.name, # Query für jedes Match!
'away_team': m.away_team.name, # Noch eine Query!
'venue': m.home_team.venue.name # Und noch eine!
} for m in matches])
```
Bei 100 Matches: 1 + 100 + 100 + 100 = **301 Queries** statt 1-4.
## WARUM WAR ES SCHLECHT?
- **Performance:** Exponentieller Anstieg der DB-Queries mit Datenmenge
- **Latenz:** Jede Query hat Overhead (Netzwerk, Parsing, Locking)
- **DB-Last:** Unnötige Belastung der Datenbank
- **Skalierung:** Funktioniert in Dev (10 Records), bricht in Prod (10.000 Records)
## DIE BESSERE ALTERNATIVE
```python
# GUT: Optimierte Queries
def get_matches(request):
matches = Match.objects.filter(
scenario_id=scenario_id
).select_related(
'home_team',
'away_team',
'home_team__venue', # Nested relation
)
return Response([{
'id': m.id,
'home_team': m.home_team.name,
'away_team': m.away_team.name,
'venue': m.home_team.venue.name
} for m in matches])
```
Bei 100 Matches: **1 Query** (mit JOINs).
## ERKENNUNGSREGELN
- `select_related()` für ForeignKey / OneToOneField
- `prefetch_related()` für ManyToMany / Reverse ForeignKey
- Django Debug Toolbar zeigt Query-Anzahl
- `django-query-counter` als Middleware
## CHECKLISTE
- [ ] Hat jeder Listen-Endpoint `select_related`/`prefetch_related`?
- [ ] Werden verschachtelte Relations berücksichtigt?
- [ ] Ist die Query-Anzahl bei >100 Records akzeptabel?