Documentationpg_stat_insights Documentation
Parallel Query Analysis
Inspect Parallel Adoption
Start by listing the busiest queries that launched parallel workers. Compare the number planned versus launched to identify executor fallbacks (e.g., due to insufficient workers).
Queries using parallel workers
SELECT queryid,
LEFT(query, 160) AS query_preview,
calls,
parallel_workers_launched,
parallel_workers_planned,
mean_exec_time,
(parallel_workers_launched::numeric / NULLIF(calls, 0)) AS avg_workers
FROM pg_stat_insights
WHERE parallel_workers_launched > 0
ORDER BY parallel_workers_launched DESC
LIMIT 20;Evaluate Parallel Speedup
Gauge efficiency by normalising execution time per worker. Small or negative gains suggest the workload is not parallel-friendly.
Execution time per worker
WITH stats AS (
SELECT queryid,
total_exec_time,
total_plan_time,
parallel_workers_launched,
calls
FROM pg_stat_insights
WHERE parallel_workers_launched > 0
)
SELECT queryid,
total_exec_time / NULLIF(calls, 0) AS avg_exec_ms,
(total_exec_time - total_plan_time) / NULLIF(parallel_workers_launched, 0) AS exec_ms_per_worker
FROM stats
ORDER BY exec_ms_per_worker ASC
LIMIT 15;Highlight Sequential Fallbacks
Queries planned for parallelism but executed serially
SELECT queryid,
parallel_workers_planned,
parallel_workers_launched,
mean_exec_time
FROM pg_stat_insights
WHERE parallel_workers_planned > 0
AND parallel_workers_launched = 0
ORDER BY mean_exec_time DESC
LIMIT 15;Reasons include disabled parallel_leader_participation, insufficient workers, or functions marked PARALLEL UNSAFE.
Tune Configuration
Recommended starting values
max_parallel_workers_per_gather = 4
max_parallel_workers = 16
max_parallel_maintenance_workers = 4
parallel_leader_participation = onEnsure max_worker_processes is set higher than max_parallel_workers, and monitor background worker contention (logical replication, autovacuum) when raising limits.
Optimise Execution Plans
Encourage parallelism
- Use
parallel_setup_costandparallel_tuple_costto adjust planner sensitivity. - Rewrite functions to be
PARALLEL SAFEwhen possible. - Partition large tables to enable partition-wise joins and aggregates.
Disable when harmful
- Set
ALTER ROLE user SET max_parallel_workers_per_gather = 0;for latency-critical clients. - Use
/*+ Parallel(0) */planner hints (via pg_hint_plan) for known hotspots. - Disable parallelism for queries with heavy locking or when CPU is saturated.