Query Optimization Basics: Complete Beginner's Guide
Query optimization is how a database turns your SQL into a fast execution plan. You write what you want ("orders from Mumbai in March"); the query optimizer decides how — which index to use, which table to read first, whether to sort or hash. A good plan runs in milliseconds; a bad one can take hours on identical data.
It matters because SQL is declarative — you never specify the steps. Two similar-looking queries can differ 1000× in speed depending on the chosen plan. The basics let you write optimizer-friendly queries and diagnose the ones it fumbles.
Key Concepts
- Execution plan: the step-by-step recipe — scan this table, probe that index, join in this order.
- Cost model: the optimizer scores each candidate plan in disk I/Os and CPU, then runs the cheapest.
- Selectivity: the fraction of rows a condition matches. 50 of 1,000,000 rows = 0.005% — highly selective, ideal for an index.
- Table statistics: row counts, distinct values, histograms. Stale statistics cause bad plans.
- Join order: the optimizer starts with the most selective table to keep intermediate results small.
- EXPLAIN: shows the chosen plan without running the query — your main diagnostic tool.
How It Works
Three stages. The parser checks syntax and builds a logical operation tree. The rewriter applies safe transformations: pushing filters below joins, flattening subqueries into joins. The cost-based optimizer then enumerates candidate physical plans — join orders, access paths — estimates each cost from statistics, and executes the winner. Missing or stale statistics make the estimates fiction, which is why DBAs run ANALYZE regularly.
Worked Example
Orders: 1,000,000 rows in 10,000 disk pages. Query: SELECT * FROM Orders WHERE CustomerID = 42, matching exactly 50 rows. An index on CustomerID exists.
- Full scan: read all 10,000 pages ≈ 10,000 page reads.
- Index scan: descend the B-tree (~3 reads), then fetch 50 rows — worst case 3 + 50 = 53 reads.
- Comparison: 10,000 ÷ 53 ≈ 189× less I/O. Selectivity is 0.005%, so the optimizer picks the index.
- Flip case: WHERE Status = 'shipped' matches 600,000 rows (60% selectivity). Index plan ≈ 600,003 reads vs 10,000 for the full scan — the optimizer correctly chooses the scan.
- Join order: joining Orders (1M) with Customers (50k) on a filter matching 50 orders — read the 50 via the index first, then probe Customers 50 times, not 1M times.
Common Misconceptions
- "An index always speeds up my query." Only if the optimizer picks it. Low selectivity, functions on indexed columns, or stale statistics can leave it unused — verify with EXPLAIN.
- "The optimizer is always right." It estimates from statistics, not facts. Skewed data routinely produces bad plans.
- "SELECT * is harmless." It defeats covering indexes and multiplies I/O. Listing needed columns is one of the cheapest optimizations.
Real-World Applications
- Dashboards: optimizers keep reports under a second on billion-row tables.
- E-commerce search: faceted filters rely on sensible multi-index plans.
- DBA tuning: reading EXPLAIN and fixing slow queries is a core admin skill.
- ORM-generated SQL: understanding plans exposes the N+1 queries frameworks emit.
Optimization is the database thinking for you: rewrite safely, estimate every plan's cost from real statistics, run the cheapest. Your side of the bargain — selective filters, fresh statistics, right indexes, and checking EXPLAIN — is small but powerful.
Related blogs
- ER Model and Relational Model: Complete Beginner's Guide
- SQL Queries: Joins, Subqueries and Views With easy examples.
- Database Normalization: 1NF to BCNF With easy examples.
- Transactions and ACID Properties: Complete Beginner's Guide
- Concurrency Control and Locking: Complete Beginner's Guide
- Indexing and B-Trees in Databases: Complete Beginner's Guide