Paths Subjects Questions Quizzes Pricing Search
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?"

  1. Explain, mechanistically, what almost certainly changed between Postgres 11 and Postgres 13 that would produce this speedup on this exact query shape.
  2. orders is a huge table (hundreds of millions of rows) and region = '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 scanning orders, and why that explains most of the speedup.
  3. A teammate proposes "let's just always add MATERIALIZED to 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

← Back to Advanced SQL: Window Functions & CTEs practice

We use cookies for product analytics to improve OmniAtlas. See our Privacy Policy.