Skip to content

bench: plan unmarked, MATERIALIZED and NOT MATERIALIZED CTEs - #27005

Merged
adriangb merged 2 commits into
apache:mainfrom
adriangb:cte-planner-benchmarks
Nov 3, 2026
Merged

adriangb merged 2 commits into
apache:mainfrom
adriangb:cte-planner-benchmarks

Conversation

@adriangb

@adriangb adriangb commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

Which issue does this PR close?

Rationale for this change

MATERIALIZED CTEs (#26271) are planned differently from inlined CTEs: each body is optimized on its own before the rest of the plan. #26428 adds more work to that step. No planner benchmark plans a materialized CTE today, so there is no standard way to see what this costs, or to compare it with inlining.

What changes are included in this PR?

New sql_planner cases, which plan a query from SQL to a physical plan. The PostgreSQL dialect is used, because sqlparser only parses [NOT] MATERIALIZED for that dialect. For each kind of CTE (unmarked, MATERIALIZED, NOT MATERIALIZED) there are three cases:

  • physical_cte_<kind>_one_ref: the CTE is read once.
  • physical_cte_<kind>_two_refs: the CTE is joined with itself.
  • physical_cte_<kind>_chain_6: six CTEs, each joining the previous one with itself.

physical_cte_mixed has one CTE of each kind, each read twice.

Results on main (Criterion means):

Case unmarked MATERIALIZED NOT MATERIALIZED
one reference 242 µs 264 µs 245 µs
two references 474 µs 360 µs 481 µs
chain of 6 8.25 ms 0.92 ms 8.33 ms

physical_cte_mixed takes 1.36 ms.

An inlined chain copies the first CTE 32 times. So it takes about 9 times as long to plan as the materialized chain.

What is the testing strategy for this PR?

This PR has only benchmarks. They run with:

cargo bench -p datafusion --bench sql_planner -- physical_cte

The sql_planner benchmark needs ClickBench data. The checked-in fixture works: put datafusion/core/tests/data/clickbench_hits_10.parquet in a directory, and set CLICKBENCH_DATA_PATH to that directory.

Are there any user-facing changes?

No.

🤖 Generated with Claude Code

Add sql_planner cases that plan a CTE read once, read twice, and a
chain of six CTEs that each read the previous one twice, for each kind
of CTE, plus one query that mixes all three.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added the core Core DataFusion crate label Nov 2, 2026

@nuno-faria nuno-faria left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @adriangb.

Comment on lines +1028 to +1030
("unmarked", ""),
("materialized", "MATERIALIZED "),
("not_materialized", "NOT MATERIALIZED "),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason to test unmarked and not materialized?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unmarked can change, e.g. postgres materializes it if it's referenced more than once. NOT MATERIALIZED is always inlined

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense, thanks.

A reviewer asked why the benchmark has both: today the planner inlines
them alike. Say in the comment that the unmarked default can change, as
in PostgreSQL, while NOT MATERIALIZED always inlines.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@adriangb
adriangb added this pull request to the merge queue Nov 3, 2026
Merged via the queue into apache:main with commit 181a87a Nov 3, 2026
43 of 44 checks passed
@adriangb
adriangb deleted the cte-planner-benchmarks branch November 3, 2026 21:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core Core DataFusion crate v57.0.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants