How to read EXPLAIN ANALYZE and what to look at first
I read from the inside out.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | -- ====================================================================== -- Q: How do you read an EXPLAIN ANALYZE? What do you look for first? -- -- I read from the inside out. I check: -- - estimated rows vs actual rows: a big difference means stale statistics -- (ANALYZE) or correlated columns (CREATE STATISTICS). -- - Seq Scan on a large table with a selective filter: an index is missing or -- cannot be used (function on the column, cast, LIKE '%x'). -- - Large Rows Removed by Filter: the index covers only part of the WHERE, maybe -- a composite or partial index is needed. -- - loops in a Nested Loop: actual time × loops is the real time. -- - Sort Method: external merge Disk: work_mem is not enough or an index is -- needed for the ORDER BY. -- - Buffers shared read vs hit: how many pages came from disk. -- In practice I start from pg_stat_statements (which queries cost the most in -- total) and then run EXPLAIN on the specific one. -- ====================================================================== EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM orders WHERE customer_id = 42 AND status = 'paid' ORDER BY created_at DESC LIMIT 20; Limit (cost=0.43..58.12 rows=20 width=96) (actual time=0.041..0.210 rows=20 loops=1) -> Index Scan using ix_orders_cust_created on orders (cost=0.43..1210.55 rows=419 width=96) (actual time=0.040..0.205 rows=20 loops=1) Index Cond: (customer_id = 42) Filter: (status = 'paid') Rows Removed by Filter: 3 Buffers: shared hit=24 Planning Time: 0.180 ms Execution Time: 0.240 ms |