Documentationpg_stat_insights Documentation
Slow Query Analysis
Rank Slow Queries
Start with average execution time to locate persistent bottlenecks. Filter by call count to ignore one-off statements.
Top 10 slowest queries
SELECT queryid,
LEFT(query, 120) AS query_preview,
calls,
mean_exec_time AS avg_ms,
total_exec_time AS total_ms,
stddev_exec_time,
rows
FROM pg_stat_insights
WHERE calls > 10
ORDER BY mean_exec_time DESC
LIMIT 10;Measure Variability
High standard deviation indicates intermittent slowness due to locking, bloated tables, or cache misses. Prioritise queries with high coefficient of variation.
Execution time variance
SELECT queryid,
stddev_exec_time,
mean_exec_time,
max_exec_time,
min_exec_time,
(stddev_exec_time / NULLIF(mean_exec_time, 0)) AS coeff_variation
FROM pg_stat_insights
WHERE stddev_exec_time > 0
ORDER BY coeff_variation DESC
LIMIT 15;Drill into Execution Plans
Use pg_stat_insights_plan to fetch the captured plan summary, then re-run the statement with EXPLAIN (ANALYZE, BUFFERS, WAL) for current statistics.
Plan investigation
-- Replace :queryid with target ID
SELECT *
FROM pg_stat_insights_plan
WHERE queryid = :queryid;
-- Capture execution plan
dO $$
DECLARE
sql TEXT;
BEGIN
SELECT query INTO sql
FROM pg_stat_insights
WHERE queryid = :queryid;
EXECUTE format('EXPLAIN (ANALYZE, BUFFERS, WAL) %s', sql);
END;
$$;Remediation Checklist
Index & schema fixes
- Create missing indexes surfaced by
EXPLAINorpg_stat_user_indexes. - VACUUM and ANALYZE bloated tables; stale statistics often cause bad plans.
- Consider partitioning large tables to minimise scanned data.
Query optimisation
- Rewrite OR chains into UNION ALL or use partial indexes.
- Push predicates closer to data sources to avoid wide joins.
- Reduce client round-trips by batching repeated lookups.
Automate Regression Detection
Store baselines
CREATE TABLE IF NOT EXISTS slow_query_baselines AS
SELECT queryid,
mean_exec_time,
total_exec_time,
calls,
now() AS captured_at
FROM pg_stat_insights
WHERE mean_exec_time > 100;Alert on regressions
#!/usr/bin/env bash
REGRESS=$(psql -t -c "SELECT queryid FROM pg_stat_insights s JOIN slow_query_baselines b USING (queryid) WHERE s.mean_exec_time > b.mean_exec_time * 1.5;")
if [[ -n "$REGRESS" ]]; then
echo "Slow query regression detected: $REGRESS" | mail -s "pg_stat_insights regression" dba@example.com
fi