Stale Query Statistics
Causes of slow queries.
Overview
Stale query statistics are one of the most common causes of suddenly slow queries in Postgres and other cost-based optimizers. The optimizer picks plans based on table statistics; when those statistics drift away from the actual data distribution, the optimizer chooses sequential scans where it should index, hash joins where it should nested-loop, and the query that was fast yesterday becomes pathological today. The fix is rarely a new index; it is making sure ANALYZE keeps pace with the writes.
- Causes of suddenly slow queries. Per-table stale stats; the optimizer picks bad plans because it is reasoning about an out-of-date snapshot of the data.
- autovacuum_analyze threshold. Per-table autovacuum trigger; default thresholds are too lax for high-write tables and let stats drift far before reanalysing.
- Manual ANALYZE. Per-table manual analyze after bulk operations; bulk inserts, deletes, and updates change distribution faster than autovacuum catches.
- Per-table tuning plus statistics target. High-write tables need aggressive analyze settings; per-column statistics target raises sample size for skewed columns.
The approach
The practical approach is per-table autovacuum tuning (lower thresholds for high-write tables), manual ANALYZE after bulk operations (do not wait for autovacuum), monitoring last_analyzed times so stale stats become visible before they cause incidents, raising statistics_target on skewed columns where the default sample misrepresents the distribution, and documenting the per-table analyze strategy so the next DBA inherits the model.
- Per-table tuning. High-write tables get tighter autovacuum_analyze thresholds; the default is fine for read-heavy tables and wrong for write-heavy ones.
- Manual ANALYZE after bulk. Per-bulk-operation manual ANALYZE; do not wait for autovacuum to catch up after a 10M-row import.
- Monitor stale stats. Per-table last_analyzed time tracked; alerting on stale stats prevents the next slow-query surprise.
- Statistics target tuning plus documented policy. Per-column statistics_target raised for skewed columns; per-table analyze strategy committed for operational review.
Why this compounds
Stats discipline compounds across queries and tables. Each well-tuned table preserves plan stability; each well-monitored table catches drift before it becomes an incident; the team builds a vocabulary for plan health that pays off on every new schema. Without the discipline, slow-query investigations re-derive the same lesson every quarter.
- Query performance. Right stats produce right plans; the optimizer chooses index scans where they belong and hash joins where they belong.
- Operational fit. Right tuning matches workload; high-write tables get high-write attention without taxing read-heavy ones.
- Incident response. Stats freshness monitoring catches optimizer regressions before users notice; the slow-query bridge starts with data, not investigation.
- Institutional knowledge. Each tuning teaches optimizer patterns; the team learns what makes plans stable rather than just what makes them fast today.
Stats discipline is a database discipline that pays off across years. Nova AI Ops integrates with database telemetry, surfaces stats freshness, and supports the team’s database engineering discipline.