SQL Practice Logo

SQLPractice Online

Query Rewriting Patterns: Functions

Module: Query Optimization & Performance

**Pattern: OR to UNION ALL**

Before (can't use indexes):

SELECT * FROM products

WHERE category = 'Electronics' OR brand = 'Apple';

-- Full table scan: 5M rows, 8 seconds

After (each branch uses index):

SELECT * FROM products WHERE category = 'Electronics'

UNION ALL

SELECT * FROM products WHERE brand = 'Apple' AND category != 'Electronics';

-- Index on category: 500K rows, 0.5s

-- Index on brand: 200K rows, 0.2s

-- Total: 0.7 seconds (11x faster)

Key: Add condition to second query to avoid duplicates

**Pattern: Subquery to JOIN**

Before (correlated subquery):

SELECT

p.product_name,

(SELECT AVG(rating) FROM reviews WHERE product_id = p.id) as avg_rating

FROM products p;

-- Subquery runs 100K times: 45 seconds

After (JOIN with GROUP BY):

SELECT

p.product_name,

AVG(r.rating) as avg_rating

FROM products p

LEFT JOIN reviews r ON p.id = r.product_id

GROUP BY p.id, p.product_name;

-- Single join: 2 seconds (22x faster)

**Pattern: NOT IN to LEFT JOIN**

Before (dangerous with NULLs):

SELECT * FROM customers

WHERE id NOT IN (SELECT customer_id FROM orders);

-- Returns 0 rows if any order has NULL customer_id

-- Also slow: 30 seconds

After (NULL-safe and fast):

SELECT c.* FROM customers c

LEFT JOIN orders o ON c.id = o.customer_id

WHERE o.customer_id IS NULL;

-- Correct results with NULLs: 2 seconds (15x faster)

**Pattern: IN to EXISTS**