SQL: ANALYZE keeps the planner honest

The optimiser costs plans from statistics gathered by ANALYZE. After a bulk load those statistics describe an empty table, so it plans for an empty table and the query takes minutes.

Code
COPY orders FROM '/tmp/orders.csv' CSV;
ANALYZE orders;                     -- do not skip this

-- What it knows:
SELECT attname, n_distinct, most_common_vals
  FROM pg_stats WHERE tablename = 'orders';

-- When it last ran:
SELECT relname, last_analyze, last_autoanalyze
  FROM pg_stat_user_tables WHERE relname = 'orders';
Output
Before ANALYZE: Nested Loop  (rows=1)      actual rows=482,110   94 s
After  ANALYZE: Hash Join    (rows=480000) actual rows=482,110  0.4 s

-- Autovacuum normally runs ANALYZE for you. It falls behind after a bulk
-- load, a restore, or a partition swap - exactly when it matters most.
Advertisement

Run this yourself in the Online Java Compiler, spin up a live REST API in the API Sandbox, or practise with Java interview questions.

Published 2026-08-25