EXPLAIN SELECT * FROM orders WHERE customer_id = 42;See summary for usage details.
EXPLAIN, vacuum, planner settings, indexing, and practical tuning recipes.
Read plans and compare query behavior.
EXPLAIN SELECT * FROM orders WHERE customer_id = 42;See summary for usage details.
EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM orders WHERE customer_id = 42;See summary for usage details.
EXPLAIN (ANALYZE, VERBOSE, BUFFERS, SETTINGS) SELECT * FROM orders WHERE customer_id = 42;See summary for usage details.
EXPLAIN (ANALYZE, FORMAT JSON) SELECT * FROM orders;See summary for usage details.
Log slow query plans automatically in the server logs.
LOAD 'auto_explain';
SET auto_explain.log_min_duration = '200ms';
SET auto_explain.log_analyze = on;See summary for usage details.
Routine health tasks that keep PostgreSQL fast.
VACUUM public.users;See summary for usage details.
VACUUM (ANALYZE) public.users;See summary for usage details.
VACUUM (FULL, ANALYZE) public.users;Requires more locking and space; use carefully.
REINDEX TABLE public.users;See summary for usage details.
ANALYZE VERBOSE public.users;See summary for usage details.
SHOW autovacuum;See summary for usage details.
Inspect or tweak optimizer behavior during investigations.
SHOW work_mem;See summary for usage details.
Increase work_mem for the current transaction only.
SET LOCAL work_mem = '256MB';See summary for usage details.
Inspect a planner estimate of OS cache availability.
SHOW effective_cache_size;See summary for usage details.
Inspect a cost parameter that influences index-vs-seqscan decisions.
SHOW random_page_cost;See summary for usage details.
Temporarily discourage sequential scans while investigating plans.
SET enable_seqscan = off;Do not use as a permanent performance fix.
SELECT schemaname, tablename, attname, n_distinct, most_common_vals
FROM pg_stats
WHERE tablename = 'orders';See summary for usage details.
Recipes users often search for when tuning SQL.
Prefer keyset pagination over deep OFFSET scans for large result sets.
SELECT *
FROM orders
WHERE (created_at, order_id) < ('2026-03-01', 1000)
ORDER BY created_at DESC, order_id DESC
LIMIT 50;See summary for usage details.
Avoid fetching unnecessary columns, especially wide rows.
SELECT order_id, customer_id, total_amount FROM orders WHERE status = 'open';See summary for usage details.
Use included columns to support index-only reads for certain queries.
CREATE INDEX idx_orders_customer_created_inc
ON orders (customer_id, created_at DESC)
INCLUDE (status, total_amount);See summary for usage details.
Chunk large writes into batches to reduce contention and WAL spikes.
UPDATE orders
SET archived_at = now()
WHERE order_id IN (
SELECT order_id FROM orders WHERE created_at < now() - interval '1 year' LIMIT 10000
);See summary for usage details.
DELETE FROM audit_log
WHERE ctid IN (
SELECT ctid FROM audit_log WHERE created_at < now() - interval '180 days' LIMIT 10000
);See summary for usage details.
Partition large time-series tables by range.
CREATE TABLE metrics (
ts timestamptz NOT NULL,
device_id bigint NOT NULL,
value numeric NOT NULL
) PARTITION BY RANGE (ts);See summary for usage details.
CREATE TABLE metrics_2026_03 PARTITION OF metrics
FOR VALUES FROM ('2026-03-01') TO ('2026-04-01');See summary for usage details.