EMZETT.
Login

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

  1. Passenden Index anlegen, hier CREATE INDEX ON bestellungen (kunde_id, datum DESC);. Bei mehrspaltigen Indizes zählt die Reihenfolge.
  2. Nur nötige Spalten holen statt SELECT *.
  3. Funktionen auf der Spalte vermeiden: WHERE lower(email) = ... nutzt einen normalen Index nicht (dafür gibt es Funktionsindizes).
  4. LIMIT und Paginierung statt alles zu laden; bei großen Seitenzahlen besser „ab dem letzten Wert“ (Keyset) als OFFSET.
  5. N+1-Problem: statt für jede Zeile eine Abfrage zu senden, mit einem JOIN oder IN (...) auf einmal holen.
  6. 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