Query Optimization
When reviewing database queries, check EXPLAIN QUERY PLAN output and flag these anti-patterns.
EXPLAIN QUERY PLAN red flags
Run EXPLAIN QUERY PLAN on any new query touching large tables. Flag these in review:
SCAN— full table scan; needs an indexUSE TEMP B-TREE FOR ORDER BY— missing index on ORDER BY columnsAUTOMATIC INDEX— SQLite created a temporary index; needs a permanent oneCORRELATED SCALAR SUBQUERY— executes once per outer row; rewrite as JOINMATERIALIZE— CTE materialized when a subquery would allow index use
Anti-patterns to flag
- Correlated subqueries in SELECT — rewrite as JOINs
- Functions on indexed columns in WHERE —
WHERE date(col) = '...'prevents index use; use range comparison instead - UNION when UNION ALL suffices — 60%+ slower due to unnecessary deduplication sort
- SELECT * — prevents covering index optimization; select only needed columns
- NOT IN with subqueries — if the subquery returns any NULL, the entire result is empty. Use
NOT EXISTSinstead. - OR without indexes on both sides — causes full scan unless both columns are indexed
See the implementing copy of this guideline for detailed examples and fix patterns.