This chapter covers the core features and capabilities of SQL Query Optimization Guide.
sql-query-optimization/
āāā README.md
āāā LICENSE
āāā sql/ # runnable, heavily-commented lessons
ā āāā 01_explain_plan_basics.sql Read a plan in both engines
ā āāā 02_index_design.sql Selectivity, composites, covering
ā āāā 03_sargable_predicates.sql WHERE clauses an index can seek
ā āāā 04_join_strategies.sql Nested loop vs hash vs merge
ā āāā 05_window_functions.sql Replace self-joins & correlated subqueries
ā āāā 06_query_rewrites.sql Equivalent shapes that run 100x faster
ā āāā 07_antipatterns.sql The recurring mistakes + fixes
ā āāā 08_pagination.sql Keyset pagination vs deep OFFSET
āāā docs/ # the runbooks (the "why")
ā āāā READING-EXECUTION-PLANS.md EXPLAIN/ANALYZE, estimate vs actual
ā āāā INDEX-DESIGN.md The index decision framework
ā āāā JOIN-STRATEGIES.md Which join, when, and how to steer it
ā āāā WINDOW-FUNCTIONS.md Pattern catalogue (ranking, running totals)
ā āāā ANTI-PATTERNS.md Field guide: smell ā why ā fix
ā āāā QUERY-REWRITE-PATTERNS.md Result-preserving rewrites
āāā examples/
āāā sample_schema.sql Portable e-commerce schema + seed data
Each sql/0X file pairs with a docs/ runbook: the .sql is the runnable
lesson you paste into a session; the .md is the deeper explanation, decision
tables, and FAQ.
(psql or mysql). Everything runs in a plain SQL session ā no extensions
required for the core lessons (a couple of optional notes mention pg_trgm /
FULLTEXT for substring search).
~320,000 rows so plans behave like production, not like a 10-row toy.
JOIN/GROUP BY and want to know *why* one form outruns another.
sql/05) require MySQL 8.0+ / MariaDB 10.2+ ā not MySQL5.7. Every other lesson works on 5.7 with the inline notes.
One note on
EXPLAIN ANALYZE: plainEXPLAINnever runs your query and isalways safe.
EXPLAIN ANALYZE*executes* it ā fine for theSELECTs here, butremember it really runs DML if you ever point it at an
INSERT/UPDATE/DELETE.
Follow this guide to get SQL Query Optimization Guide up and running in your environment.
# --- PostgreSQL ---
createdb sqlopt_demo
# Open examples/sample_schema.sql, keep the PostgreSQL seed block (Block A), then:
psql -d sqlopt_demo -f examples/sample_schema.sql
# Read your first plan: a full scan before any index on customer_id.
psql -d sqlopt_demo -c "EXPLAIN (ANALYZE, BUFFERS) \
SELECT id, status, total_cents FROM orders WHERE customer_id = 12345;"
# Work through the lessons in order (they reference the same schema):
psql -d sqlopt_demo -f sql/01_explain_plan_basics.sql# --- MySQL / MariaDB ---
mysql -e "CREATE DATABASE sqlopt_demo;"
# Open examples/sample_schema.sql, keep the MySQL seed block (Block B), then:
mysql sqlopt_demo < examples/sample_schema.sql
mysql sqlopt_demo -e "EXPLAIN \
SELECT id, status, total_cents FROM orders WHERE customer_id = 12345;"Then read docs/READING-EXECUTION-PLANS.md alongside sql/01 ā that pairing is
the foundation everything else builds on.
sql/01 + READING-EXECUTION-PLANS.md ā how to read a plan in both engines,the estimate-vs-actual mental model, the loops multiplier everyone misreads,
and the five questions to ask every plan. Don't skip this; the rest assumes it.
sql/02 + INDEX-DESIGN.md ā selectivity (will an index even help?), theleftmost-prefix rule, composite column ordering, covering/index-only scans, and
partial/expression indexes. The decision framework, not a list of CREATE INDEX
statements.
sql/03 (sargability) ā the unforgiving rule that a wrapped column can't besought, and the rewrite for each way people accidentally break it: functions,
arithmetic, implicit casts, leading wildcards, OR, and the NOT IN/NULL trap.
sql/04 + JOIN-STRATEGIES.md ā the three physical joins, when each is*correct* (a hash join on a big aggregate is right, not a bug), and how to steer
the optimizer with stats and indexes rather than hints.
sql/05 + WINDOW-FUNCTIONS.md ā running totals, ranking, top-N-per-group,dedup, and LAG/LEAD, each replacing an O(n²) self-join or correlated
subquery.
sql/06 + QUERY-REWRITE-PATTERNS.md ā logically-identical rewrites thatrun far cheaper: correlated subquery ā join, IN/EXISTS/JOIN, UNION ā
UNION ALL, predicate push-down, and the CTE materialization trap.
sql/07 + ANTI-PATTERNS.md ā the field guide. Smell ā why it hurts ā fix,with a one-screen quick-reference table to scan during a review.
sql/08 (pagination) ā why deep OFFSET melts under load and how keyset /seek pagination makes every page cost the same, including the index that makes
it O(1) and how to handle total counts cheaply.
examples/sample_schema.sql ā a portable e-commerce schema (~20k customers,~100k orders, ~200k line items) with separate PostgreSQL and MySQL seed blocks.
A couple of indexes are deliberately *left out* so the lessons can add them and
measure the difference.
Get the full SQL Query Optimization Guide and unlock everything.
Get the complete guide with every chapter unlocked, including code samples, diagrams, and best practices.
Access all interactive tools with complete data, all workload profiles, and the full scenario library.
Downloadable source code, configuration files, and working examples from every chapter.
Free updates for life. Every new chapter, tool, and improvement included.