Abfragen optimieren mit EXPLAIN
Kurz: Eine langsame Datenbankabfrage lässt sich fast immer erklären: Die Datenbank liest zu viele Zeilen. Mit EXPLAIN sieht man, wie sie vorgeht, und kann gezielt eingreifen.
EXPLAIN lesen
EXPLAIN ANALYZE
SELECT * FROM bestellungen WHERE kunde_id = 42 ORDER BY datum DESC LIMIT 10;Wichtig ist die Art des Zugriffs:
- Seq Scan (Full Table Scan): die ganze Tabelle wird gelesen. Bei großen Tabellen langsam.
- Index Scan / Index Only Scan: ein Index führt direkt zu den Zeilen, siehe SQL-Index.
- Zeilen geschätzt und tatsächlich, Zeit und Sortierungen. Große Abweichungen zwischen Schätzung und Wirklichkeit deuten auf veraltete Statistiken (
ANALYZE).
Häufige Maßnahmen
- Passenden Index anlegen, hier
CREATE INDEX ON bestellungen (kunde_id, datum DESC);. Bei mehrspaltigen Indizes zählt die Reihenfolge. - Nur nötige Spalten holen statt
SELECT *. - Funktionen auf der Spalte vermeiden:
WHERE lower(email) = ...nutzt einen normalen Index nicht (dafür gibt es Funktionsindizes). LIMITund Paginierung statt alles zu laden; bei großen Seitenzahlen besser „ab dem letzten Wert“ (Keyset) alsOFFSET.- N+1-Problem: statt für jede Zeile eine Abfrage zu senden, mit einem
JOINoderIN (...)auf einmal holen. - Zu viele Indizes verlangsamen Schreiben und kosten Platz.
Vorgehen
Erst messen (langsame Abfragen protokollieren, EXPLAIN ANALYZE), dann ändern, dann erneut messen. Auf Testdaten mit Produktionsgröße prüfen: Auf 100 Zeilen sind alle Pläne schnell.
Siehe auch: Datenbank-Transaktionen und ACID, Caching-Strategien