Leistungsbesprechung: „PostgreSQL hält der Last nicht stand. » Wir diskutieren über ein leistungsfähigeres Gremium. Jemand plant „EXPLAIN ANALYZE“ für die Produktsuche:
Seq Scan auf Produkten (Kosten=0..84291 Zeilen=1 Breite=120) (tatsächliche Zeit=412..412 ms Zeilen=50)
Filter: (category_id = 7 UND Preis < 100)
Durch Filter entfernte Zeilen: 890000
412 Millisekunden für 50 Zeilen – 890.000 Zeilen gefiltert. Zusammengesetzter Index „(category_id, price)“ fehlt. Es handelt sich nicht um ein Cloud-Prozessor-Problem, sondern um ein Ausführungsplanproblem.
EXPLAIN wandelt „es ist langsam“ in einen lesbaren Mechanismus um. Ohne sie optimieren Sie willkürlich – oder zahlen für eine größere Instanz, um dieselbe gesamte Tabelle schneller zu scannen.
Einen Plan lesen: Grundlegender Wortschatz
| Knoten | Bedeutung | Warnung |
|---|---|---|
| Seq. Scan | Lesen der gesamten Tabelle | Große Tabelle, wenige zurückgegebene Zeilen |
| Index-Scan | Index durchsuchen | Gut, wenn selektiv |
| Bitmap-Index-Scan | Mehrere Indizes kombiniert | Zwischenkompromiss |
| Verschachtelte Schleife | Join-Schleife | Korrekt klein × indiziert; Schlecht, wenn inner im sequentiellen Scan |
| Hash-Join | Hash-Tabelle im Speicher | Speicherverbrauch überwachen |
| Schicksal | Explizite Sortierung | Teuer, wenn das Volumen groß ist |
Wichtige Kennzahlen in „EXPLAIN ANALYZE“:
- tatsächliche Zeit Start..Ende pro Knoten
- Geschätzte vs. tatsächliche Zeilen – schlechte Statistiken führen zu einem schlechten Plan
- Puffer gemeinsam genutzter Hit/Read – heißer oder kalter Cache
Eine geschätzte/tatsächliche Differenz multipliziert mit Hundert in Bezug auf die Anzahl der Zeilen → Führen Sie „ANALYZE table“ aus, bevor Sie einen nutzlosen Index erstellen.
Diagnose-Workflow in fünfzehn Minuten
- Aktivieren Sie pg_stat_statements:
- Kopieren Sie die Schuldabfrage → „EXPLAIN (ANALYZE, BUFFERS, TEXT FORMAT)...“.
- Identifizieren Sie den teuersten Knoten (Zeit × Linien).
- Stellen Sie eine Hypothese auf: Index, Join-Umschreibung, Cursor-Paging.
- Nachmessen; Vergleichen Sie mean_exec_time unter realer Last.
„sql SELECT-Abfrage, Aufrufe, mittlere_exec_time, total_exec_time FROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT 10; „
Gängige Webbeispiele
Starkes OFFSET-Paging
„sql SELECT * FROM Articles ORDER BY veröffentlicht_at DESC OFFSET 50000 LIMIT 20;
→ Paginierung nach Cursor: `(published_at, id) < ($last, $id)`.
**ANZAHL(*) auf einem Marketing-Dashboard**
Vollständiger Scan – materialisierte Ansicht oder denormalisierter Zähler.
**JSONB ohne GIN-Index**
`WHERE data->>'status' = 'active'` → GIN-Index oder indizierte generierte Spalte.
## Statistik und Wartung
- Regelmäßige „VAKUUMANALYSE“ mit automatischer Vakuumanpassung.
– „default_statistics_target“ höher bei gefilterten Spalten mit verzerrter Verteilung.
- Nach einer massiven Migration: veraltete Statistiken = vorübergehend katastrophale Pläne.
Verwaltetes PostgreSQL (RDS, Scaleway, OVH): pg_stat_statements können oft aktiviert werden; EXPLAIN funktioniert genauso wie selbst gehostet. Informationen zur Auswahl zwischen verwaltetem und VPS finden Sie unter [Verwaltetes PostgreSQL](/de/blog/postgres-manage/).
## Der Gipfel: Der Plan lügt, wenn die Statistiken lügen – aber er lügt weniger als die Intuition
Hier ist, was in den „Lasst uns die Instanz upgraden“-Meetings vergessen wurde zu zeigen.
:::Höhepunkt
**Der Kauf von IOPS ohne EXPLAIN beschleunigt die falsche Reise.** PostgreSQL zeigt Ihnen genau, welche Zeilen es gelesen hat, um fünfzig zurückzugeben – die Weigerung, den Plan zu lesen, bedeutet, das Standard-Upgrade zu wählen.
:::
Teamkultur: **Keine „langsamen Abfrage“-Tickets, die ohne einen Vorher-/Nachher-Plan geschlossen werden** – auch wenn die Korrektur in eine Indexzeile passt.
## Entscheide dich und gehe ohne blinden Fleck voran
Innerhalb eines halben Tages können Sie eine PostgreSQL-Diagnosekultur etablieren:
1. **Aktivieren** Sie pg_stat_statements in der Produktion.
2. **Analysieren** Sie die fünf teuersten Abfragen mit EXPLAIN ANALYZE in der Vorproduktion.
3. **Erstellen** Sie einen Index oder schreiben Sie die Abfrage neu – messen Sie den verschlüsselten Gewinn.
4. **Führen** Sie ANALYZE nach jedem massiven Datenimport aus.
5. **Korrelieren** Sie langsame Anwendungsrouten mit SQL-Abfragen über Ihr Überwachungstool.
Beginnen Sie mit der Abfrage, die die längste Gesamtzeit hat – nicht mit der Abfrage, die in einem einzelnen Durchgang am langsamsten ist. Siehe [Datenbankreplikation](/de/blog/replication-base-donnees/) und [Fehlender MySQL-Index](/de/blog/mysql-index-manquant/) für die Parallele auf der MySQL-Seite.
## Häufig gestellte Fragen
### Was ist der Unterschied zwischen EXPLAIN und EXPLAIN ANALYZE?
EXPLAIN schätzt den Plan, ohne die Abfrage auszuführen. EXPLAIN ANALYZE führt es tatsächlich aus und zeigt die gemessenen Zeiten an – zur Verwendung in der Vorproduktion oder bei konservativen SELECTs, niemals bei einem massiven DELETE in der Produktion.
### Ist Seq Scan immer schlecht?
Nein. Bei einem kleinen Tisch oder wenn die meisten Zeilen umgedreht sind, ist das sequentielle Scannen möglicherweise optimal. Dies ist ein schlechtes Zeichen für eine große Tabelle mit wenigen zurückgegebenen Zeilen und vielen gefilterten Zeilen.
### Wie erkennt man einen fehlenden Index?
Suchen Sie nach einem sequentiellen Scan mit einer hohen Anzahl gefilterter Zeilen und einer dominanten Ausführungszeit. Erstellen Sie den Index, führen Sie EXPLAIN ANALYZE erneut aus und vergleichen Sie die Vorher- und Nachher-Zeiten.
### Reicht pg_stat_statements aus?
Nicht allein. pg_stat_statements identifiziert, welche Abfragen die meiste Gesamtzeit verbrauchen; EXPLAIN erklärt warum. Die beiden Tools ergänzen sich für eine umsetzbare Diagnose.
---
Hören Sie auf zu raten, warum PostgreSQL hinterherhinkt – lassen Sie sich vom Plan auf den richtigen Weg bringen.
