Langsame Django-Seiten entstehen häufig durch viele kleine Datenbankabfragen. Bevor Sie eine Abfrage ändern, erfassen Sie deshalb den betroffenen Request und die darin ausgeführten SQL-Anweisungen. Halten Sie die Datenmenge und die benötigten Ausgabefelder fest. So lässt sich erkennen, ob die Zeit in der Datenbank, beim Laden von Beziehungen oder bei der Verarbeitung in Python verloren geht.
Beziehungen passend laden
select_related() lädt passende einzelne Beziehungen über einen SQL-Join. prefetch_related() holt verknüpfte Objekte über zusätzliche Abfragen und ordnet sie in Python zu. Im vorhandenen Modell müssen die genannten Beziehungen tatsächlich existieren. Das Beispiel zeigt unterschiedliche Möglichkeiten; wählen Sie die Variante, die zu Ihrer Ausgabe passt.
# Importieren der Modelle
from meineapp.models import MeinModell
# Verwendung von select_related für ForeignKey-Beziehungen
meine_objekte = MeinModell.objects.select_related('verknuepftes_modell').all()
# Verwendung von prefetch_related für ManyToMany- und Reverse ForeignKey-Beziehungen
meine_objekte = MeinModell.objects.prefetch_related('andere_verknuepfte_modelle').all()
# Begrenzung der abgerufenen Felder mit only und defer
meine_objekte = MeinModell.objects.all().only('feld1', 'feld2')
meine_objekte = MeinModell.objects.all().defer('feld3', 'feld4')
Felder und Ergebnismengen begrenzen
Wenn Sie nur einzelne Werte benötigen, können values() oder values_list() geeigneter sein als vollständige Modellobjekte. Begrenzen Sie große Listen bereits in der Abfrage und verwenden Sie eine stabile Sortierung. Achten Sie darauf, welche Daten das Template tatsächlich liest: Ein dort nachträglich benötigtes, zurückgestelltes Feld kann weitere Abfragen auslösen.
Ein QuerySet wird erst bei seiner Auswertung ausgeführt. Untersuchen Sie daher auch Schleifen, Eigenschaften und Template-Zugriffe. Es genügt nicht, nur die Zeile mit filter() zu betrachten. Ein Cache hilft nur, wenn Schlüssel, Zugriffsrechte und Invalidierung zu den Daten passen.
Eine Änderung mit derselben Aufgabe vergleichen
Vergleichen Sie Abfragezahl, Laufzeit und Speicherverbrauch unter derselben fachlichen Last. Testen Sie neben einer kleinen Liste auch einen großen Bestand und den Zugriff auf leere Beziehungen. Überprüfen Sie dabei, ob die Ausgabe vollständig bleibt. Weniger Abfragen können mit größeren Joins oder mehr geladenen Objekten verbunden sein.
Eine Optimierung ist dann nützlich, wenn sie einen gemessenen Engpass beseitigt und sich im Projekt nachvollziehen lässt. Dokumentieren Sie die Ausgangssituation und den Vergleich, statt eine pauschale Beschleunigung für jedes Modell zu erwarten.
Weiterführende Dokumentation: Django: Database access optimization.