Skip to content

perf: avoid repeated row copies in literal CASE branches - #27160

Open
killme2008 wants to merge 3 commits into
apache:mainfrom
killme2008:perf/case-literal-selection-upstream
Open

killme2008 wants to merge 3 commits into
apache:mainfrom
killme2008:perf/case-literal-selection-upstream

Conversation

@killme2008

@killme2008 killme2008 commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

Which issue does this PR close?

Related: GreptimeTeam#38

Rationale for this change

CASE expressions with literal WHEN values and nonliteral THEN expressions repeatedly copy unmatched rows, including string keys in partitioned join filters.

What changes are included in this PR?

Keep remaining row indices between branches and materialize selected rows for THEN/ELSE. Nonliteral WHEN expressions retain the existing path.

Performance measurements below use e6dfc8f8f9, including the nested-field-name compatibility fix.

Baseline 90b55e38b, M4 Max/48 GiB, Rust 1.99.1, release-nonlto; 8,192 rows and two 32-byte string keys. Criterion: ABA/BAB/ABA, 20 samples, 0.5s warmup and 1s measurement per block; three-round means:

CASE distribution Baseline This PR Speedup
Uniform, 1 branch 16.669 µs 16.722 µs 0.997×
Uniform, 4 branches 225.847 µs 152.109 µs 1.485×
Uniform, 16 branches 418.673 µs 229.322 µs 1.826×
First branch only, 4 branches 16.700 µs 16.690 µs 1.001×
First branch only, 16 branches 16.777 µs 16.789 µs 0.999×
1 WHEN + ELSE, 50% match 138.987 µs 135.901 µs 1.023×

Uniform 4/16-branch maximum bracket drift was 3.9%. The 50% match case measured 1.041×/1.002×/1.025× across rounds, with maximum drift 2.4%. The mean change in the 50% match case is smaller than its maximum bracket drift.

The existing integer-column CASE measured 1.087× with maximum drift 5.1%. Unchanged lookup/no-base controls ranged from 1.000× to 1.005×; their maximum bracket drift was 11.6%.

What is the testing strategy for this PR?

Physical-expression tests cover row mapping, duplicate/NULL WHEN branches, error short-circuiting, zero-column batches and differing nested field names. The benchmark checks output before timing. Extended workspace tests (13,529 passed, 8 ignored), 546 SQLLogicTest files, clippy and formatting pass.

Are there any user-facing changes?

Performance only; SQL semantics and APIs are unchanged.

Signed-off-by: Dennis Zhuang <killme2008@gmail.com>
Signed-off-by: Dennis Zhuang <killme2008@gmail.com>
@github-actions github-actions Bot added the physical-expr Changes to the physical-expr crates label Nov 6, 2026
@killme2008
killme2008 marked this pull request as ready for review November 6, 2026 08:28
Signed-off-by: Dennis Zhuang <killme2008@gmail.com>
@killme2008

Copy link
Copy Markdown
Contributor Author

@pepijnve @rluvaton, would you have time to review this CASE evaluation change?

It keeps row indices between literal WHEN branches to avoid repeatedly copying unmatched rows. Given your work on CASE evaluation, I'd appreciate your feedback. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

physical-expr Changes to the physical-expr crates

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant