Question presented to candidate: "You run EXPLAIN ANALYZE on a slow query. Explain every number on a node line — cost, actual time, rows, loops — and what the Buffers lines tell you. What patterns tell you where the problem is?"
What a strong answer should cover:
EXPLAIN ANALYZEexecutes the query and prints, next to each estimate, what really happened:actual time=first..lastin milliseconds,rowsandloops;costand the firstrowsare still the planner estimatesrowsandtimeare per loop: a node withrows=10 loops=5produced 50 rows; the inner side of a Nested Loop is where loops matter- The most useful signal is an estimate vs actual mismatch (e.g. 40 expected, 200 actual), usually from stale or missing statistics or correlated columns; fixes are
ANALYZE, a higher statistics target, orCREATE STATISTICS(PostgreSQL 10+) BUFFERS:shared hit(found in PostgreSQL shared buffers),read(fetched from the OS / disk),dirtied,written, andtemp read/writtenfor spills; each buffer is an 8 kB page; PostgreSQL 18 shows BUFFERS by default with ANALYZE- Other lines to read:
Rows Removed by Filter,Sort Method: external merge Diskvsquicksort Memory(work_mem),Heap Fetches,Batcheson a Hash,Planning Time/Execution Time - Cautions: ANALYZE really runs
INSERT/UPDATE/DELETE(wrap inBEGIN ... ROLLBACK), timing has overhead (TIMING OFF), and the first run may read from disk while later runs hit cache
Code / implementation expected: Optional — an EXPLAIN (ANALYZE, BUFFERS) output read line by line, with a misestimate and its fix.
Schema used by the examples: