If the query planner makes bad decisions it’s mostly one of two things:
1. The statistics are inaccurate.
Do you run ANALYZE
enough? Also popular in it’s combined form VACUUM ANALYZE
. If autovacuum is on (which is the default in modern-day Postgres), ANALYZE
is run automatically. But consider:
(Top two answers still apply for Postgres 12.)
If your table is big and data distribution is irregular, raising the default_statistics_target
may help. Or rather, just set the statistics target for relevant columns (those in WHERE
or JOIN
clauses of your queries, basically):
ALTER TABLE ... ALTER COLUMN ... SET STATISTICS 400; -- calibrate number
The target can be set in the range 0 to 10000;
Run ANALYZE
again after that (on relevant tables).
2. The cost settings for planner estimates are off.
Read the chapter Planner Cost Constants in the manual.
Look at the chapters default_statistics_target and random_page_cost on this generally helpful PostgreSQL Wiki page.
There are many other possible reasons, but these are the most common ones by far.