SQL Practice Logo

SQLPractice Online

CTE Performance Optimization: Real-World

Module: Subqueries & CTEs

CTEs make queries readable but can cause performance disasters if misused. A Shopify dashboard query with CTEs took 45 seconds - users complained. Analysis showed: (1) CTE scanned 50M rows without filtering, (2) CTE referenced 3 times but not materialized (executed 3 times), (3) No indexes on join columns. After optimization: filter in CTE (scan 500K rows), add MATERIALIZED hint (execute once), create indexes. Result: 0.8 seconds (56x faster). Understanding CTE performance is critical for production systems.

Shopify: Merchant Dashboard Optimization

Shopify merchant dashboard showed sales metrics with multiple CTEs. Original query took 45 seconds - merchants complained. Analysis revealed: CTE scanned 50M orders without filtering, CTE referenced 3 times but not materialized, no indexes on join columns. After optimization: 0.8 seconds (56x faster).

Reduced dashboard load time from 45s to 0.8s (56x faster). Merchants get instant insights. Improved user satisfaction and retention. Enabled real-time analytics for 2M+ merchants. Critical for platform scalability. Optimization techniques: filter early (100x improvement), materialize reused CTEs (3x improvement), create indexes (60x improvement).

Optimized dashboard query with filtering, materialization, and indexes

-- BEFORE: 45 seconds (multiple issues)

WITH all_orders AS (

SELECT *

FROM orders -- 50M rows, no filtering!

)

SELECT 'High Value' as segment, COUNT(*), SUM(amount)

FROM all_orders

WHERE order_date >= '2024-01-01' AND amount > 1000

UNION ALL

SELECT 'Medium Value', COUNT(*), SUM(amount)

FROM all_orders

WHERE order_date >= '2024-01-01' AND amount BETWEEN 100 AND 1000

UNION ALL

SELECT 'Low Value', COUNT(*), SUM(amount)

FROM all_orders

WHERE order_date >= '2024-01-01' AND amount < 100;

-- AFTER: 0.8 seconds (all issues fixed)

CREATE INDEX idx_orders_date_amount ON orders(order_date, amount);

WITH recent_orders AS MATERIALIZED (

SELECT order_id, merchant_id, amount, order_date

FROM orders

WHERE order_date >= '2024-01-01' -- Filter IN CTE

)

SELECT 'High Value' as segment, COUNT(*), SUM(amount)

FROM recent_orders WHERE amount > 1000

UNION ALL

SELECT 'Medium Value', COUNT(*), SUM(amount)

FROM recent_orders WHERE amount BETWEEN 100 AND 1000

UNION ALL

SELECT 'Low Value', COUNT(*), SUM(amount)

FROM recent_orders WHERE amount < 100;

-- Improvements:

-- 1. Filter in CTE: 50M → 500K rows (100x less)

-- 2. MATERIALIZED: Execute once, not 3 times

-- 3. Index: Index scan instead of sequential scan