CodeGym /Kurse /SQL SELF /Langsame Abfragen tracken mit pg_stat_statements

Langsame Abfragen tracken mit pg_stat_statements

SQL SELF
Level 42 , Lektion 2
Verfügbar

pg_stat_statements ist ein eingebautes PostgreSQL-Extension, das dir zeigt, welche Queries wirklich in deiner Datenbank ablaufen und wie sie sich verhalten. Im Prinzip ist das so ein stiller, aber aufmerksamer Helfer, der jeden Schritt mitloggt: welche SQL-Queries ausgeführt wurden, wie lange sie gebraucht haben, wie oft sie liefen und wie sehr sie das System belasten.

Wozu das Ganze? Erstens, um Problem-Queries zu finden. Manchmal ist die Datenbank nicht wegen einem Bösewicht langsam, sondern weil zig gleiche, schwere Queries viel zu oft laufen. Zweitens hilft dir die Statistik zu checken, welche Queries Ressourcen fressen – CPU, RAM, Disk. Und du kannst auch sehen, ob deine Indexe so arbeiten, wie du’s geplant hast: Vielleicht werden sie irgendwo gar nicht genutzt, oder an anderer Stelle fehlen sie komplett.

pg_stat_statements sorgt dafür, dass du nicht raten musst, sondern echte Zahlen siehst – und darauf basierend kannst du dann optimieren.

Wie findet man langsame Queries?

Jetzt wird’s spannend! Mit der Tabelle pg_stat_statements kannst du Queries suchen, die lange laufen oder den Server stark belasten.

Die Grundidee:

Jede Zeile in der Tabelle pg_stat_statements steht für die Statistik zu einer Query. Die Queries werden nach ihrem Text gruppiert (das Feld query), und für jede werden folgende Metriken gezählt:

  • total_time – die gesamte Ausführungszeit der Query, in Millisekunden.
  • calls – wie oft die Query ausgeführt wurde.
  • mean_time – durchschnittliche Ausführungszeit (total_time / calls).
  • rows – wie viele Zeilen die Query zurückgegeben hat.

Einfaches Analysebeispiel

Lass uns die langsamsten Queries nach durchschnittlicher Ausführungszeit finden:

SELECT
    query,
    mean_time,
    calls,
    rows
FROM
    pg_stat_statements
ORDER BY
    mean_time DESC
LIMIT 5;

Diese Query zeigt dir die TOP-5 der langsamsten Queries. Schau dir das Feld mean_time an: Wenn die Werte da über 500-1000 Millisekunden liegen, ist das ein Zeichen, dass du optimieren solltest.

Beispielanalyse langsamer Queries

Schauen wir uns ein Beispiel an:

Hier ist das Ergebnis der vorherigen Query:

query mean_time calls rows
SELECT * FROM orders WHERE status = 'neu'; 1234.56 10 10000
SELECT * FROM products 755.12 5000 100
SELECT * FROM customers WHERE id = $1 543.21 1000 1

Was sehen wir hier?

Query auf die Tabelle orders: Wird sehr selten ausgeführt (nur 10 Aufrufe), aber jedes Mal werden riesige 10.000 Zeilen gezogen. Wahrscheinlich ist die Tabelle ziemlich groß und die Query nutzt keine Indexe.

Query auf die Tabelle products: Wird tausende Male aufgerufen, vielleicht in einer Schleife in der App. Jede Auswahl gibt nur 100 Zeilen zurück, aber wegen der Häufigkeit kann auch diese Query ein Problem sein.

Query auf die Tabelle customers: Läuft schnell (543 ms), aber wird viel zu oft ausgeführt.

Optimierung langsamer Queries

Jetzt, wo wir die Problem-Queries gefunden haben, sollten wir uns deren Ausführungsplan mit EXPLAIN ANALYZE anschauen. Zum Beispiel für die Query auf die Tabelle orders:

EXPLAIN ANALYZE
SELECT * FROM orders WHERE status = 'neu';

Was kann man da sehen?

Seq Scan: Wenn die Query einen sequentiellen Scan macht, solltest du einen Index hinzufügen:

CREATE INDEX idx_orders_status ON orders (status);

Probleme mit Filtern: Wenn die Query zu viele Zeilen zieht, überleg dir, ob du den Query-Text anpasst. Vielleicht brauchst du zusätzliche Bedingungen oder solltest die Ergebnisse begrenzen:

SELECT * FROM orders WHERE status = 'neu' LIMIT 100;

Statistik-Ausgabe nach Ausführungszeit

Manchmal sind Problem-Queries nicht so offensichtlich. Zum Beispiel Queries, die oft Funktionen oder Subqueries aufrufen. In solchen Fällen ist es praktisch, sich die Spalte total_time anzuschauen:

SELECT
    query,
    total_time,
    calls,
    mean_time
FROM
    pg_stat_statements
ORDER BY
    total_time DESC
LIMIT 10;

Diese Query zeigt dir die "teuersten" Queries nach gesamter Ausführungszeit.

Index-Optimierung

Oft sind langsame Queries mit fehlenden Indexen verbunden. Nutze pg_stat_statements, um zu checken, welche Queries keine Indexe nutzen. Wenn du viele Queries mit gleichen Filtern siehst (zum Beispiel auf das Feld status), die aber sehr langsam sind, leg einen passenden Index an:

CREATE INDEX idx_orders_status ON orders (status);

Danach prüf die Performance der Query nochmal mit EXPLAIN ANALYZE.

Mit pg_stat_statements kannst du die Query-Performance easy überwachen, "Bottlenecks" finden und die Performance deiner Datenbank verbessern. Denk dran: Je früher du mit der Query-Analyse anfängst, desto leichter wird’s, das ganze System zu optimieren.

Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION