Was dieses Tool leistet
PostgreSQLs EXPLAIN ANALYZE sagt Ihnen genau, wie eine Abfrage ausgeführt wurde — aber die rohe Ausgabe ist bekanntlich schwer zu lesen. Zeiten sind inklusiv (die Zeit jedes Knotens enthält alle seine Kindknoten), Zeilenanzahlen sind pro Schleife gemittelt, und der eigentliche Engpass steckt oft drei Ebenen tief im Baum.
Dieser Visualizer parst den Plan und zeigt für jeden Knoten:
- Exklusive Zeit — die im Knoten selbst verbrachte Zeit, berechnet als seine Gesamtzeit (× Schleifen) minus der Zeit seiner Kindknoten, mit einem farbigen Balken proportional zu seinem Anteil an der gesamten Abfrage.
- Geschätzte vs. tatsächliche Zeilen — die Zeilenschätzung des Planers neben dem, was tatsächlich herauskam, mit dem Fehlschätzungsfaktor, wenn sie auseinanderlaufen.
- Buffers-, Filter-, Sort- und Hash-Details, sofern sie im Plan vorhanden sind.
So erhalten Sie einen Plan
Führen Sie Ihre Abfrage aus mit:
EXPLAIN (ANALYZE, BUFFERS)
SELECT ... your query ...;
und fügen Sie das Ergebnis oben ein — sowohl das voreingestellte Klartextformat als auch FORMAT JSON werden unterstützt. BUFFERS ist optional, aber empfehlenswert — es zeigt, wie viel I/O jeder Knoten durchgeführt hat. Sie können direkt aus psql einfügen: die Kopfzeile QUERY PLAN und die Zeilenfortsetzungszeichen + werden automatisch bereinigt.
⚠️ EXPLAIN ANALYZE führt die Abfrage tatsächlich aus. Bei einem INSERT/UPDATE/DELETE umschließen Sie es mit BEGIN; ... ROLLBACK;.
Einen Plan teilen
Teilen-Link kopieren kodiert den gesamten Plan komprimiert in die URL selbst (den Teil nach #). Es wird nichts irgendwohin hochgeladen — das Fragment erreicht nicht einmal unseren Webserver — sodass das Null-Upload-Versprechen gilt. Die Kehrseite ist erwähnenswert: der Link enthält den Plan, sodass jeder, dem Sie ihn senden, darin Tabellennamen, Filterwerte und Zeilenanzahlen lesen kann. Sehr große Pläne erzeugen sehr lange URLs; manche Chat-Tools kürzen diese, in welchem Fall der Empfänger einen klaren Fehler statt eines falschen Plans erhält.
Warnungen, die dieses Tool erkennt
- Zeilenschätzung um mehr als das 10-Fache daneben — der Planer erwartete eine deutlich andere Zeilenzahl, als er erhielt. Schlechte Schätzungen führen kaskadierend zu schlechten Join-Strategien. Typische Abhilfen:
ANALYZEfür die Tabelle ausführen, das Statistikziel der Spalte erhöhen oder erweiterte Statistiken für korrelierte Spalten hinzufügen. - Sequenzieller Scan über viele Zeilen mit einem Filter — der Executor las die ganze Tabelle, um nur einen Teil davon zu behalten. Oft ein Zeichen, dass ein Index helfen würde.
- Sortierung, die auf die Festplatte auslagert —
Sort Method: external mergebedeutet, dass die Sortierung nicht inwork_mempasste und temporäre Dateien nutzte. - Hash, der auf die Festplatte auslagert — ein Hash-Knoten mit mehr als einem Batch musste Partitionen auf die Festplatte schreiben; die Hashtabelle passte nicht in
work_mem. - Teurer Nested Loop — die innere Seite eines Nested Loop wurde vielfach ausgeführt und macht einen erheblichen Anteil an der Gesamtlaufzeit aus.
- Viele durch einen Filter entfernte Zeilen — der Knoten erzeugte weit weniger Zeilen, als er prüfen musste, was auf einen fehlenden oder wenig selektiven Index hindeutet.
- Knoten nie ausgeführt wird ebenfalls markiert (loops = 0), damit Knoten mit null Zeit die Lesart nicht durcheinanderbringen.
Flame-Graph und Baum lesen
Das Flame-Graph oben zeigt die gesamte Abfrage auf einen Blick: jeder Balken ist ein Planknoten, seine Breite ist die insgesamt darin verbrachte Zeit (Kindknoten inklusive) und seine Farbe zeigt, wie viel der Abfragezeit die eigene Arbeit des Knotens ist — grün für günstig, rot für heiß. Ein breiter roter Balken weit unten ist Ihr Engpass; klicken Sie ihn an, um zum entsprechenden Knoten im Baum zu springen.
Im Baum beginnt die Ausführung an den Blättern (Scans) und fließt nach oben zur Wurzel. Der horizontale Balken an jedem Knoten ist sein exklusiver Zeitanteil: ein roter Balken an einem Blatt-Seq-Scan bedeutet, dass die Zeit wirklich beim Scannen verbraucht wird, nicht im Join darüber. Klicken Sie auf einen Knoten-Header, um seine Details auszuklappen — Kosten, Zeilenanzahlen, Filterbedingungen, Buffer-Nutzung — und nutzen Sie Textzusammenfassung kopieren, um einen kompakten Bericht in ein Ticket oder einen Chat einzufügen.
Hinweis zu parallelen Abfragen: die Zeitzuordnung über parallele Worker hinweg ist eine Näherung — Kindknoten eines Gather-Knotens melden Schleifen pro Worker, sodass exklusive Zeiten dort als Richtwert zu lesen sind.
