SQL Query Optimizer
Prerequisites & Dependencies
- PostgreSQL 13+ / MySQL 8+ / MariaDB 10.6+ (or SQLite 3.30+) instance with query access
- Client tooling:
psql or mysql CLI; pg_stat_statements enabled (recommended) for PostgreSQL workload profiling
DATABASE_URL (or engine-specific credentials) with privileges to run EXPLAIN and create indexes on the target schema
Execution Steps
- Capture the slow query and its execution context: bind parameter values, call frequency, and current latency from query logs or APM traces.
- Generate the actual execution plan:
EXPLAIN (ANALYZE, BUFFERS) on PostgreSQL, EXPLAIN ANALYZE FORMAT=JSON on MySQL; save the plan output.
- Locate the costliest plan nodes: sequential scans on large tables, nested-loop joins over unindexed columns, sorts/hashes spilling to disk, implicit type casts.
- Propose indexes that match filter (
WHERE), join (ON), and sort (ORDER BY) columns; prefer composite indexes with equality columns first and covering (INCLUDE) columns for hot read paths.
- Restructure the query: replace correlated subqueries with
JOIN/EXISTS, push predicates as early as possible, drop SELECT *, and pre-aggregate where feasible.
- Apply recommended indexes in the development environment, re-run
EXPLAIN ANALYZE, and record before/after timings and buffer hits.
- Benchmark under production-like data volume, confirm no write-path regressions, then schedule production index creation with
CONCURRENTLY/online DDL.
-- Baseline plan
EXPLAIN (ANALYZE, BUFFERS)
SELECT o.id, c.email, SUM(li.qty * li.price) AS total
FROM orders o
JOIN customers c ON c.id = o.customer_id
JOIN line_items li ON li.order_id = o.id
WHERE o.status = 'paid' AND o.created_at >= NOW() - INTERVAL '30 days'
GROUP BY o.id, c.email;
-- Recommended indexes (verify selectivity before applying)
CREATE INDEX CONCURRENTLY idx_orders_status_created
ON orders (status, created_at DESC);
CREATE INDEX CONCURRENTLY idx_line_items_order
ON line_items (order_id) INCLUDE (qty, price);
-- Rewrite: filter early, EXISTS instead of IN-subquery
SELECT o.id, c.email
FROM orders o
JOIN customers c ON c.id = o.customer_id
WHERE o.status = 'paid'
AND o.created_at >= NOW() - INTERVAL '30 days'
AND EXISTS (SELECT 1 FROM line_items li WHERE li.order_id = o.id);
1---2name: sql-query-optimizer3description: Analyze slow SQL queries, recommend indexes, and restructure join clauses.4---56# SQL Query Optimizer78## Prerequisites & Dependencies9- PostgreSQL 13+ / MySQL 8+ / MariaDB 10.6+ (or SQLite 3.30+) instance with query access10- Client tooling: `psql` or `mysql` CLI; `pg_stat_statements` enabled (recommended) for PostgreSQL workload profiling11- `DATABASE_URL` (or engine-specific credentials) with privileges to run `EXPLAIN` and create indexes on the target schema1213## Execution Steps141. Capture the slow query and its execution context: bind parameter values, call frequency, and current latency from query logs or APM traces.152. Generate the actual execution plan: `EXPLAIN (ANALYZE, BUFFERS)` on PostgreSQL, `EXPLAIN ANALYZE FORMAT=JSON` on MySQL; save the plan output.163. Locate the costliest plan nodes: sequential scans on large tables, nested-loop joins over unindexed columns, sorts/hashes spilling to disk, implicit type casts.174. Propose indexes that match filter (`WHERE`), join (`ON`), and sort (`ORDER BY`) columns; prefer composite indexes with equality columns first and covering (`INCLUDE`) columns for hot read paths.185. Restructure the query: replace correlated subqueries with `JOIN`/`EXISTS`, push predicates as early as possible, drop `SELECT *`, and pre-aggregate where feasible.196. Apply recommended indexes in the development environment, re-run `EXPLAIN ANALYZE`, and record before/after timings and buffer hits.207. Benchmark under production-like data volume, confirm no write-path regressions, then schedule production index creation with `CONCURRENTLY`/online DDL.2122```sql23-- Baseline plan24EXPLAIN (ANALYZE, BUFFERS)25SELECT o.id, c.email, SUM(li.qty * li.price) AS total26FROM orders o27JOIN customers c ON c.id = o.customer_id28JOIN line_items li ON li.order_id = o.id29WHERE o.status = 'paid' AND o.created_at >= NOW() - INTERVAL '30 days'30GROUP BY o.id, c.email;3132-- Recommended indexes (verify selectivity before applying)33CREATE INDEX CONCURRENTLY idx_orders_status_created34 ON orders (status, created_at DESC);35CREATE INDEX CONCURRENTLY idx_line_items_order36 ON line_items (order_id) INCLUDE (qty, price);3738-- Rewrite: filter early, EXISTS instead of IN-subquery39SELECT o.id, c.email40FROM orders o41JOIN customers c ON c.id = o.customer_id42WHERE o.status = 'paid'43 AND o.created_at >= NOW() - INTERVAL '30 days'44 AND EXISTS (SELECT 1 FROM line_items li WHERE li.order_id = o.id);45```46