Was macht dieses Tool?
pg_slow_query_digest analysiert die in pg_stat_statements gesammelten Query-Statistiken und liefert eine nach Gesamtlaufzeit sortierte Liste der langsamsten Queries. Anders als ein einfaches SELECT * FROM pg_stat_statements ORDER BY total_exec_time DESC normalisiert das Tool die Ausgabe, berechnet Durchschnittswerte pro Aufruf und identifiziert Queries, die durch ihre Häufigkeit × Dauer die meisten Ressourcen verbrauchen.
Wie wird es aufgerufen?
Verbindung herstellen
Bevor ein Performance-Tool aufgerufen werden kann, muss eine Verbindung zur Zieldatenbank hergestellt werden. mcp-postgres unterstützt mehrere Datenbankprofile — ideal für Multi-Cluster-Setups:
▶ Calling tools...
→ pg_connect { "profile": "production-db" }
{
"status": "connected",
"database": "mcp_test",
"version": "PostgreSQL 16.x",
"host": "db.example.com"
}
Claude CLI (natürliche Sprache)
▶ Calling tools...
→ pg_slow_query_digest {}
Hier sind die 2 langsamsten Queries nach Gesamtlaufzeit:
1. SELECT * FROM app.orders WHERE status = $1
847 Aufrufe, Ø 12.4ms, Max 89.2ms, Gesamt: 10.5s
→ Kandidat für einen Index auf app.orders(status)
2. SELECT u.*, o.* FROM app.users u JOIN app.orders o...
234 Aufrufe, Ø 8.7ms, Max 45.1ms, Gesamt: 2.0s
→ Join-Query mit hohem Row Count pro Aufruf (12)
MCP Protocol (programmatisch)
const result = await client.callTool("pg_slow_query_digest", {});
// Response:
{
"slow_queries": [
{
"queryid": "9069661048250515891",
"query_preview": "ANALYZE",
"calls": "3",
"total_time_ms": "1522.52",
"mean_time_ms": "507.51",
"stddev_ms": "59.49",
"rows": "0",
"pct_total": "46.76"
},
{
"queryid": "-8526373234667933857",
"query_preview": "DO $$\nBEGIN\n FOR i IN 1..20 LOOP\n PERFORM count(*) FROM perf.transactions...",
"calls": "1",
"total_time_ms": "510.39",
"mean_time_ms": "510.39",
"stddev_ms": "0.00",
"rows": "0",
"pct_total": "15.68"
},
{
"queryid": "3348334810192286589",
"query_preview": "INSERT INTO perf.transactions (transaction_id, account_id, ...)...",
"calls": "1",
"total_time_ms": "483.69",
"mean_time_ms": "483.69",
"stddev_ms": "0.00",
"rows": "100000",
"pct_total": "14.86"
},
{
"queryid": "4800951176609648582",
"query_preview": "ANALYZE perf.transactions",
"calls": "1",
"total_time_ms": "110.56",
"mean_time_ms": "110.56",
"stddev_ms": "0.00",
"rows": "0",
"pct_total": "3.40"
}
]
}
Was passiert unter der Haube?
Das Tool führt folgende SQL-Query gegen pg_stat_statements aus:
SELECT queryid, query AS query_preview, calls, total_exec_time AS total_time_ms, total_exec_time / calls AS mean_time_ms, stddev_exec_time AS stddev_ms, rows, total_exec_time * 100.0 / sum(total_exec_time) OVER() AS pct_total FROM pg_stat_statements WHERE calls > 0 ORDER BY total_exec_time DESC LIMIT 20;
Voraussetzung: Die Extension pg_stat_statements muss geladen sein (shared_preload_libraries = 'pg_stat_statements'). Das Tool prüft das automatisch und gibt einen klaren Fehler, wenn die Extension nicht verfügbar ist.
Ausgabe im Detail
- queryid — Eindeutige ID der normalisierten Query aus pg_stat_statements
- query_preview — Vorschau der Query (gekürzt bei langen Statements)
- calls — Wie oft die Query seit dem letzten Reset aufgerufen wurde
- total_time_ms — Gesamte Ausführungszeit in Millisekunden — die Sortiergrundlage
- mean_time_ms — Durchschnittliche Ausführungszeit pro Aufruf
- stddev_ms — Standardabweichung — hohe Werte deuten auf instabile Performance hin
- rows — Gesamtanzahl zurückgegebener Zeilen
- pct_total — Anteil an der Gesamtlaufzeit aller Queries in Prozent
Praxis-Tipp: Eine Query mit hohem total_ms aber niedrigem mean_ms wird nicht durch Einzelaufrufe langsam — sondern durch die schiere Menge an Aufrufen. Hier hilft oft ein Connection Pool oder Query-Caching, nicht ein Index.
Was testet die Testsuite?
Die Testsuite validiert pg_slow_query_digest gegen eine PostgreSQL 16-Instanz mit 300.000 Finanztransaktionen in der perf-Schema und realistischem Query-Muster:
✓ pg_slow_query_digest > includes calls, mean_ms, max_ms fields
✓ pg_slow_query_digest > sorts by total execution time descending
✓ pg_slow_query_digest > respects limit parameter
Test Files 1 passed (1)
Tests 4 passed (4)
Duration 312ms
Testdaten-Szenario
Die Seed-Datenbank enthält:
- perf.transactions — 300.000 Zeilen (33 MB) mit Betrag, Währung, Status, Region, Kanal
- pg_stat_statements — Automatisch befüllt durch die Testläufe selbst
Die Tests validieren, dass:
- Das Ergebnis ein Array mit Query-Objekten ist (nicht leer)
- Jedes Objekt die erwarteten Felder enthält (
calls,mean_time_ms,pct_total) - Die Sortierung nach
total_time_msabsteigend korrekt ist - Der
limit-Parameter die Ergebnismenge begrenzt
Zusammenfassung
pg_slow_query_digest ist das erste Tool, das ein DBA bei Performance-Problemen aufrufen sollte. Es ersetzt das manuelle Query-Graben in pg_stat_statements durch eine strukturierte, sortierte und sofort verwertbare Ausgabe.
In Kombination mit pg_index_advisor (→ fehlende Indizes) und pg_cache_hit_ratio (→ Buffer-Effizienz) bildet es den Kern des /pg-perf Workflow-Skills.