-- Table sizes
SELECTtablename,pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename))ASsizeFROMpg_tablesWHEREschemaname='public'ORDERBYpg_total_relation_size(schemaname||'.'||tablename)DESC;-- Row counts (estimate)
SELECTrelnameAStable,reltuples::bigintASrow_estimateFROMpg_classWHERErelkind='r'ANDrelnamespace='public'::regnamespaceORDERBYreltuplesDESC;-- Exact row counts (slow on large tables)
SELECT'SELECT '''||tablename||''' AS table, COUNT(*) FROM '||tablename||' UNION ALL'FROMpg_tablesWHEREschemaname='public';
-- Index sizes
SELECTindexrelnameASindex,pg_size_pretty(pg_relation_size(indexrelid))ASsizeFROMpg_stat_user_indexesORDERBYpg_relation_size(indexrelid)DESC;-- Unused indexes
SELECTschemaname||'.'||relnameAStable,indexrelnameASindex,idx_scanASscansFROMpg_stat_user_indexesWHEREidx_scan=0ORDERBYpg_relation_size(indexrelid)DESC;-- Index usage
SELECTrelnameAStable,indexrelnameASindex,idx_scanASscans,idx_tup_readAStuples_read,idx_tup_fetchAStuples_fetchedFROMpg_stat_user_indexesORDERBYidx_scanDESC;
-- Show query plan with actual timing
EXPLAINANALYZESELECT*FROMusersWHEREemail='test@example.com';-- With buffers (I/O stats)
EXPLAIN(ANALYZE,BUFFERS)SELECT*FROMusersWHEREemail='test@example.com';-- Format as JSON
EXPLAIN(ANALYZE,FORMATJSON)SELECT*FROMusersWHEREemail='test@example.com';
-- Simple index
CREATEINDEXidx_users_emailONusers(email);-- Unique index
CREATEUNIQUEINDEXidx_users_emailONusers(email);-- Partial index
CREATEINDEXidx_orders_pendingONorders(created_at)WHEREstatus='pending';-- Multi-column index
CREATEINDEXidx_orders_user_dateONorders(user_id,created_atDESC);
-- Index on lowercase email
CREATEINDEXidx_users_email_lowerONusers(LOWER(email));-- Query must match expression
SELECT*FROMusersWHERELOWER(email)='test@example.com';
-- Update statistics
ANALYZEusers;ANALYZE;-- All tables
-- Reclaim space
VACUUMusers;VACUUMFULLusers;-- Locks table, reclaims more space
-- Check auto-vacuum status
SELECTschemaname,relname,last_vacuum,last_autovacuum,last_analyze,last_autoanalyzeFROMpg_stat_user_tables;
-- Rebuild index
REINDEXINDEXidx_users_email;-- Rebuild all indexes on table
REINDEXTABLEusers;-- Concurrent (doesn't lock)
REINDEXINDEXCONCURRENTLYidx_users_email;
-- Current connections
SELECTcount(*)FROMpg_stat_activity;-- By state
SELECTstate,count(*)FROMpg_stat_activityGROUPBYstate;-- By application
SELECTapplication_name,count(*)FROMpg_stat_activityGROUPBYapplication_name;
-- Database size
SELECTpg_size_pretty(pg_database_size('mydb'));-- Largest tables
SELECTrelname,pg_size_pretty(pg_total_relation_size(relid))FROMpg_stat_user_tablesORDERBYpg_total_relation_size(relid)DESCLIMIT10;-- Cache hit ratio (should be > 99%)
SELECTsum(heap_blks_hit)/(sum(heap_blks_hit)+sum(heap_blks_read))ASratioFROMpg_statio_user_tables;-- Connection states
SELECTstate,count(*)FROMpg_stat_activityGROUPBYstate;-- Replication lag (if applicable)
SELECTclient_addr,state,pg_wal_lsn_diff(pg_current_wal_lsn(),replay_lsn)ASlag_bytesFROMpg_stat_replication;
PostgreSQL is remarkably capable once you know how to look under the hood. These queries solve 90% of operational questions.
📬 Get the Newsletter
Weekly insights on DevOps, automation, and CLI mastery. No spam, unsubscribe anytime.