Query tuning maximizes PostgreSQL performance by analyzing execution plans, adding indexes, rewriting SQL, and adjusting planner settings.
Query tuning is the systematic way of making SQL run faster by inspecting execution plans, creating the right indexes, and rewriting queries so the planner picks the cheapest path.
EXPLAIN ANALYZE shows the actual execution plan and runtime statistics. It reveals whether PostgreSQL uses indexes or sequential scans, how many rows flow between nodes, and where time is spent.
Start at the most indented node—that is the first operation executed. Compare estimated rows (rows) to actual rows (actual). Large differences suggest outdated statistics or missing indexes.
Turn on SET track_io_timing = on
to see I/O wait, and use SET enable_seqscan = off
to force index usage temporarily when testing alternatives.
Add an index when filters or joins on a column touch a small fraction of the table. Use multicolumn or expression indexes for composite predicates such as WHERE customer_id = ? AND order_date > now()-'30 days'::interval
.
Replace SELECT *
with required columns, push predicates into sub-queries or CTEs, and prefer EXISTS
over IN
for correlated subqueries. Remove unnecessary DISTINCT and ORDER BY.
After creating an index, run ANALYZE
so PostgreSQL updates statistics and starts using the new access path immediately.
Bulk insert or update using COPY or multi-row INSERT to reduce commit overhead and avoid bloating indexes.
No. It runs the query and discards results, so data remains unchanged. Use it freely on production if the query itself is safe.
Enable track_activity_query_size
and inspect pg_stat_activity
or add EXPLAIN (BUFFERS)
to view shared/hit buffer counts, which correlate with memory.
Use it only for testing. Disabling sequential scans globally can force inefficient index plans. Re-enable default behavior afterward.