100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace

SQL Query Optimization Cheat Sheet

SQL Query Optimization Cheat Sheet

Provides practical techniques for reading EXPLAIN plans, indexing strategy, and rewriting slow SQL queries to reduce latency and resource use.

2 PagesAdvancedMar 2, 2026

Reading EXPLAIN ANALYZE

Spot the warning signs in a Postgres query plan.

sql
EXPLAIN ANALYZESELECT o.id, c.nameFROM orders oJOIN customers c ON o.customer_id = c.idWHERE o.status = 'pending';-- Look for:-- Seq Scan on large tables -> missing index-- Nested Loop with high row estimates -> consider hash/merge join-- "actual time" vs "cost" mismatch -> stale statistics, run ANALYZE-- rows=X (estimated) vs actual rows=Y -> large gap means bad planner estimate

Index Types

Different index structures and when to use them.

  • B-tree index- Default index type; supports equality and range queries (<, >, BETWEEN), sorted output
  • Hash index- Supports only equality lookups, faster than B-tree for exact matches but no range support
  • Composite (multi-column) index- Indexes multiple columns together; column order matters — matches queries that filter on a leading prefix of the columns
  • Partial index- Indexes only rows matching a WHERE condition (e.g., WHERE status = 'active'), smaller and faster for narrow queries
  • Covering index- Includes all columns a query needs so the engine can answer from the index alone without hitting the table (index-only scan)
  • GIN / GiST index- Postgres index types for full-text search, arrays, JSONB, and geometric data

Creating Effective Indexes

Composite, partial, and covering index examples.

sql
-- Composite index: order matters, put the equality column firstCREATE INDEX idx_orders_status_date ON orders (status, created_at);-- Partial index for a common filtered queryCREATE INDEX idx_orders_pending ON orders (created_at) WHERE status = 'pending';-- Covering index (Postgres INCLUDE) avoids a table lookupCREATE INDEX idx_orders_cover ON orders (customer_id) INCLUDE (status, total);-- Build without locking writes on a live tableCREATE INDEX CONCURRENTLY idx_orders_customer ON orders (customer_id);

Query Optimization Checklist

Common fixes for slow queries.

  • Avoid SELECT *- Fetch only needed columns to reduce I/O and enable covering/index-only scans
  • Sargable predicates- Avoid wrapping indexed columns in functions (e.g., WHERE YEAR(created_at)=2024) since it prevents index use; rewrite as a range
  • LIMIT with ORDER BY- Pair LIMIT with an indexed ORDER BY column so the planner can stop early instead of sorting the full result
  • N+1 queries- Looping and issuing one query per row instead of a single JOIN or batched IN() query kills performance
  • Statistics freshness- Run ANALYZE (Postgres) or UPDATE STATISTICS (SQL Server) after large data changes so the planner's row estimates stay accurate
  • Batch large writes- Break huge UPDATE/DELETE statements into chunks to avoid long locks and huge transaction logs
Pro Tip

When EXPLAIN shows a Seq Scan on a large table, don't assume you automatically need an index — check pg_stat_user_tables first; the planner may be choosing a seq scan because the table is small or the predicate isn't selective enough for an index to pay off.

Was this cheat sheet helpful?

Explore Topics

#SQLQueryOptimization#SQLQueryOptimizationCheatSheet#Database#Advanced#ReadingEXPLAINANALYZE#IndexTypes#CreatingEffectiveIndexes#QueryOptimizationChecklist#Databases#CheatSheet#SkillVeris
Advertisement
Sri Hayavadhana Info-Tech

Professional Web Designing Services

  • Responsive Websites
  • E-commerce Solutions
  • SEO Friendly Design
  • Fast & Secure
  • Support & Maintenance
Get a Free Quote

Share this Cheat Sheet