0
0
PostgreSQLquery~10 mins

CTE materialization behavior in PostgreSQL - Step-by-Step Execution

Choose your learning style9 modes available
Concept Flow - CTE materialization behavior
Start Query Execution
Identify CTE
Materialize CTE Result
Use Materialized Result in Main Query
Return Final Result
End
The query execution first identifies the CTE, fully computes and stores its result (materializes it), then uses this stored result in the main query before returning the final output.
Execution Sample
PostgreSQL
WITH cte AS (
  SELECT id FROM users WHERE active = true
)
SELECT * FROM cte WHERE id > 10;
This query first computes the CTE by selecting active users, materializes the result, then filters those with id > 10.
Execution Table
StepActionCTE ComputationMain Query ActionOutput Rows
1Start query executionNot startedNot startedNone
2Compute CTESelect active users: ids 5, 12, 15Waiting for CTENone
3Materialize CTE resultStore rows (5,12,15)Waiting for CTENone
4Execute main query using CTEMaterialized rows usedFilter id > 10Rows with ids 12, 15
5Return final resultCTE result reusedOutput filtered rowsRows with ids 12, 15
6End query executionCTE fully usedMain query doneFinal output returned
💡 Query ends after main query uses the fully materialized CTE result.
Variable Tracker
VariableStartAfter Step 2After Step 3After Step 4Final
CTE ResultEmptyRows (5,12,15) computedRows (5,12,15) storedRows (5,12,15) reusedRows (5,12,15) reused
Main Query OutputEmptyEmptyEmptyRows (12,15) filteredRows (12,15) output
Key Moments - 3 Insights
Why does the CTE compute all rows before the main query starts?
Because PostgreSQL materializes the CTE result first (see execution_table step 3), it fully computes and stores the CTE before the main query uses it.
Can the main query see changes made after the CTE is materialized?
No, since the CTE is materialized (stored) at step 3, the main query uses this fixed snapshot, ignoring any later changes.
What happens if the CTE is large?
Materializing a large CTE means storing many rows in memory or disk before the main query runs, which can impact performance (see variable_tracker for stored rows).
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what rows does the CTE contain after step 3?
ARows with ids 12, 15 only
BRows with ids 5, 12, 15
CNo rows yet
DAll users regardless of active status
💡 Hint
Check the 'CTE Computation' column at step 3 in the execution_table.
At which step does the main query start filtering rows?
AStep 4
BStep 3
CStep 2
DStep 5
💡 Hint
Look at the 'Main Query Action' column in the execution_table.
If the CTE was not materialized, what would change in the execution flow?
AMain query would execute before CTE
BCTE result would be empty
CCTE would be computed repeatedly for each main query row
DNo change at all
💡 Hint
Materialization means storing once; without it, the CTE might be recomputed multiple times.
Concept Snapshot
CTE Materialization in PostgreSQL:
- CTEs are computed fully and stored before main query runs.
- Main query uses this stored snapshot, not live data.
- Materialization can impact performance for large CTEs.
- Helps isolate CTE execution from main query.
- Syntax: WITH cte AS (SELECT ...) SELECT ... FROM cte;
Full Transcript
In PostgreSQL, when you use a Common Table Expression (CTE), the database first computes the CTE fully and stores its result. This process is called materialization. After the CTE is materialized, the main query runs using this stored data. This means the main query does not see any changes made after the CTE was computed. Materialization ensures the CTE result is stable and isolated, but it can affect performance if the CTE is large because all rows must be stored before continuing. The execution flow starts with query execution, then CTE computation and storage, followed by main query execution using the stored CTE result, and finally returning the output.