Intermediate
Open
Pro
A Multi-Step CTE Pipeline Suddenly Got Slow After a Postgres Upgrade
A dbt model (relevant background in dbt-and-analytics-engineering)
runs this shape of query on Postgres, and it consistently completed in
under 2 seconds:
WITH filtered_orders AS (
SELECT *
FROM orders
WHERE order_date >= CURRENT_DATE - INTERVAL '30 days'
),
enriched AS (
SELECT
fo.*,
c.region
FROM filtered_orders fo
JOIN customers c ON c.customer_id = fo.customer_id
)
SELECT region, SUM(amount) AS total
FROM enriched
WHERE region = 'EMEA'
GROUP BY region;
After the team upgraded from Postgres 11 to Postgres 13, this exact query now runs in under 200 milliseconds — a 10x improvement nobody changed the query to achieve. A teammate is confused: "we didn't touch the SQL, why did it get faster on its own?"
- Explain, mechanistically, what almost certainly changed between Postgres 11 and Postgres 13 that would produce this speedup on this exact query shape.
ordersis a huge table (hundreds of millions of rows) andregion = 'EMEA'only matches roughly 15% of customers. Explain specifically how the query plan differs between the two versions in terms of what gets filtered before scanningorders, and why that explains most of the speedup.- A teammate proposes "let's just always add
MATERIALIZEDto every CTE to be safe and consistent, regardless of version." Is that good general advice? Give a case where it would help and a case where it would hurt.
Share this question