Uh oh!
There was an error while loading. Please reload this page.
perf: simplify HashJoinExec dynamic filter, drop CASE routing - #21931
perf: simplify HashJoinExec dynamic filter, drop CASE routing#21931adriangb wants to merge 10 commits into
Conversation
adriangb
commented
Apr 29, 2026
run benchmark tcph baseline:
ref: mainenv:
DATAFUSION_EXECUTION_PARQUET_PUSHDOWN_FILTERS: falseDATAFUSION_EXECUTION_PARQUET_REORDER_FILTERS: falsechanged:
ref: HEADenv:
DATAFUSION_EXECUTION_PARQUET_PUSHDOWN_FILTERS: falseDATAFUSION_EXECUTION_PARQUET_REORDER_FILTERS: false |
adriangb
commented
Apr 29, 2026
run benchmark tcph baseline:
ref: mainenv:
DATAFUSION_EXECUTION_PARQUET_PUSHDOWN_FILTERS: trueDATAFUSION_EXECUTION_PARQUET_REORDER_FILTERS: truechanged:
ref: HEADenv:
DATAFUSION_EXECUTION_PARQUET_PUSHDOWN_FILTERS: trueDATAFUSION_EXECUTION_PARQUET_REORDER_FILTERS: true |
adriangbot
commented
Apr 29, 2026
🤖 Criterion benchmark running (GKE) | trigger CPU Details (lscpu)Comparing HEAD (7a8272f) to main diff File an issue against this benchmark runner |
adriangbot
commented
Apr 29, 2026
Benchmark for this request failed. Last 20 lines of output: Click to expandFile an issue against this benchmark runner |
adriangbot
commented
Apr 29, 2026
🤖 Criterion benchmark running (GKE) | trigger CPU Details (lscpu)Comparing HEAD (7a8272f) to main diff File an issue against this benchmark runner |
adriangbot
commented
Apr 29, 2026
Benchmark for this request failed. Last 20 lines of output: Click to expandFile an issue against this benchmark runner |
adriangb
commented
Apr 29, 2026
run benchmark tpch baseline:
ref: mainenv:
DATAFUSION_EXECUTION_PARQUET_PUSHDOWN_FILTERS: trueDATAFUSION_EXECUTION_PARQUET_REORDER_FILTERS: truechanged:
ref: HEADenv:
DATAFUSION_EXECUTION_PARQUET_PUSHDOWN_FILTERS: trueDATAFUSION_EXECUTION_PARQUET_REORDER_FILTERS: true |
adriangb
commented
Apr 29, 2026
run benchmark tpch baseline:
ref: mainenv:
DATAFUSION_EXECUTION_PARQUET_PUSHDOWN_FILTERS: falseDATAFUSION_EXECUTION_PARQUET_REORDER_FILTERS: falsechanged:
ref: HEADenv:
DATAFUSION_EXECUTION_PARQUET_PUSHDOWN_FILTERS: falseDATAFUSION_EXECUTION_PARQUET_REORDER_FILTERS: false |
adriangbot
commented
Apr 29, 2026
🤖 Benchmark running (GKE) | trigger CPU Details (lscpu)Comparing HEAD (7a8272f) to main diff using: tpch File an issue against this benchmark runner |
adriangbot
commented
Apr 29, 2026
🤖 Benchmark running (GKE) | trigger CPU Details (lscpu)Comparing HEAD (7a8272f) to main diff using: tpch File an issue against this benchmark runner |
adriangbot
commented
Apr 29, 2026
🤖 Benchmark completed (GKE) | trigger Instance: CPU Details (lscpu)DetailsResource Usagetpch — base (merge-base)
tpch — branch
File an issue against this benchmark runner |
adriangbot
commented
Apr 29, 2026
🤖 Benchmark completed (GKE) | trigger Instance: CPU Details (lscpu)DetailsResource Usagetpch — base (merge-base)
tpch — branch
File an issue against this benchmark runner |
adriangb
commented
Apr 29, 2026
run benchmark tpch baseline:
ref: mainenv:
DATAFUSION_EXECUTION_TARGET_PARTITIONS=128DATAFUSION_EXECUTION_PARQUET_PUSHDOWN_FILTERS: falseDATAFUSION_EXECUTION_PARQUET_REORDER_FILTERS: falsechanged:
ref: HEADenv:
DATAFUSION_EXECUTION_TARGET_PARTITIONS=128DATAFUSION_EXECUTION_PARQUET_PUSHDOWN_FILTERS: falseDATAFUSION_EXECUTION_PARQUET_REORDER_FILTERS: false |
adriangbot
commented
Apr 29, 2026
Hi @adriangb, your benchmark configuration could not be parsed (#21931 (comment)). Error: Supported benchmarks:
Usage: Per-side configuration ( env:
SHARED_SETTING: enabledbaseline:
ref: v45.0.0env:
DATAFUSION_RUNTIME_MEMORY_LIMIT: 1Gchanged:
ref: v46.0.0env:
DATAFUSION_RUNTIME_MEMORY_LIMIT: 2GFile an issue against this benchmark runner |
adriangb
commented
Apr 29, 2026
run benchmark tpch baseline:
ref: mainenv:
DATAFUSION_EXECUTION_TARGET_PARTITIONS=128DATAFUSION_EXECUTION_PARQUET_PUSHDOWN_FILTERS: trueDATAFUSION_EXECUTION_PARQUET_REORDER_FILTERS: truechanged:
ref: HEADenv:
DATAFUSION_EXECUTION_TARGET_PARTITIONS=128DATAFUSION_EXECUTION_PARQUET_PUSHDOWN_FILTERS: trueDATAFUSION_EXECUTION_PARQUET_REORDER_FILTERS: true |
adriangbot
commented
Apr 29, 2026
Hi @adriangb, your benchmark configuration could not be parsed (#21931 (comment)). Error: Supported benchmarks:
Usage: Per-side configuration ( env:
SHARED_SETTING: enabledbaseline:
ref: v45.0.0env:
DATAFUSION_RUNTIME_MEMORY_LIMIT: 1Gchanged:
ref: v46.0.0env:
DATAFUSION_RUNTIME_MEMORY_LIMIT: 2GFile an issue against this benchmark runner |
adriangb
commented
Apr 29, 2026
run benchmark tpch baseline:
ref: mainenv:
DATAFUSION_EXECUTION_TARGET_PARTITIONS: 128DATAFUSION_EXECUTION_PARQUET_PUSHDOWN_FILTERS: falseDATAFUSION_EXECUTION_PARQUET_REORDER_FILTERS: falsechanged:
ref: HEADenv:
DATAFUSION_EXECUTION_TARGET_PARTITIONS: 128DATAFUSION_EXECUTION_PARQUET_PUSHDOWN_FILTERS: falseDATAFUSION_EXECUTION_PARQUET_REORDER_FILTERS: false |
adriangb
commented
Apr 29, 2026
run benchmark tpch baseline:
ref: mainenv:
DATAFUSION_EXECUTION_TARGET_PARTITIONS: 128DATAFUSION_EXECUTION_PARQUET_PUSHDOWN_FILTERS: trueDATAFUSION_EXECUTION_PARQUET_REORDER_FILTERS: truechanged:
ref: HEADenv:
DATAFUSION_EXECUTION_TARGET_PARTITIONS: 128DATAFUSION_EXECUTION_PARQUET_PUSHDOWN_FILTERS: trueDATAFUSION_EXECUTION_PARQUET_REORDER_FILTERS: true |
adriangbot
commented
Apr 29, 2026
🤖 Benchmark running (GKE) | trigger CPU Details (lscpu)Comparing HEAD (18129fe) to main diff using: tpch File an issue against this benchmark runner |
adriangbot
commented
Apr 29, 2026
🤖 Benchmark running (GKE) | trigger CPU Details (lscpu)Comparing HEAD (18129fe) to main diff using: tpch File an issue against this benchmark runner |
adriangbot
commented
Apr 29, 2026
🤖 Benchmark completed (GKE) | trigger Instance: CPU Details (lscpu)DetailsResource Usagetpch — base (merge-base)
tpch — branch
File an issue against this benchmark runner |
adriangbot
commented
Apr 29, 2026
🤖 Benchmark completed (GKE) | trigger Instance: CPU Details (lscpu)DetailsResource Usagetpch — base (merge-base)
tpch — branch
File an issue against this benchmark runner |
474734c to
f717a99Compareadriangb
commented
Apr 29, 2026
run benchmarks clickbench_partitioned tpch tpch10 tpcds hj env:
DATAFUSION_EXECUTION_PARQUET_PUSHDOWN_FILTERS: "false"DATAFUSION_EXECUTION_PARQUET_REORDER_FILTERS: "false"baseline:
ref: mainchanged:
ref: HEAD |
adriangbot
commented
May 17, 2026
🤖 Benchmark running (GKE) | trigger CPU Details (lscpu)Comparing HEAD (42adf29) to main diff using: clickbench_partitioned File an issue against this benchmark runner |
adriangbot
commented
May 17, 2026
🤖 Benchmark completed (GKE) | trigger Instance: CPU Details (lscpu)DetailsResource Usagetpcds — base (merge-base)
tpcds — branch
File an issue against this benchmark runner |
adriangbot
commented
May 17, 2026
🤖 Benchmark running (GKE) | trigger CPU Details (lscpu)Comparing HEAD (42adf29) to main diff using: tpch File an issue against this benchmark runner |
adriangbot
commented
May 17, 2026
🤖 Benchmark running (GKE) | trigger CPU Details (lscpu)Comparing HEAD (42adf29) to main diff using: tpch10 File an issue against this benchmark runner |
adriangbot
commented
May 17, 2026
🤖 Benchmark running (GKE) | trigger CPU Details (lscpu)Comparing HEAD (42adf29) to main diff using: tpcds File an issue against this benchmark runner |
adriangbot
commented
May 17, 2026
🤖 Criterion benchmark running (GKE) | trigger CPU Details (lscpu)Comparing HEAD (42adf29) to main diff File an issue against this benchmark runner |
adriangbot
commented
May 17, 2026
Benchmark for this request failed. Last 20 lines of output: Click to expandFile an issue against this benchmark runner |
adriangbot
commented
May 17, 2026
🤖 Benchmark completed (GKE) | trigger Instance: CPU Details (lscpu)DetailsResource Usageclickbench_partitioned — base (merge-base)
clickbench_partitioned — branch
File an issue against this benchmark runner |
adriangbot
commented
May 17, 2026
🤖 Benchmark completed (GKE) | trigger Instance: CPU Details (lscpu)DetailsResource Usagetpch — base (merge-base)
tpch — branch
File an issue against this benchmark runner |
adriangbot
commented
May 17, 2026
🤖 Benchmark completed (GKE) | trigger Instance: CPU Details (lscpu)DetailsResource Usagetpch10 — base (merge-base)
tpch10 — branch
File an issue against this benchmark runner |
adriangbot
commented
May 17, 2026
🤖 Benchmark completed (GKE) | trigger Instance: CPU Details (lscpu)DetailsResource Usageclickbench_partitioned — base (merge-base)
clickbench_partitioned — branch
File an issue against this benchmark runner |
adriangbot
commented
May 17, 2026
🤖 Benchmark completed (GKE) | trigger Instance: CPU Details (lscpu)DetailsResource Usagetpcds — base (merge-base)
tpcds — branch
File an issue against this benchmark runner |
adriangb
commented
May 17, 2026
run benchmarks tpch10 baseline:
ref: mainenv:
DATAFUSION_EXECUTION_PARQUET_PUSHDOWN_FILTERS: "false"DATAFUSION_EXECUTION_PARQUET_REORDER_FILTERS: "false"changed:
ref: HEADenv:
DATAFUSION_EXECUTION_PARQUET_PUSHDOWN_FILTERS: "true"DATAFUSION_EXECUTION_PARQUET_REORDER_FILTERS: "true" |
adriangb
commented
May 17, 2026
The only regressions are |
adriangb
commented
May 17, 2026
run benchmarks tpch10 baseline:
ref: mainenv:
DATAFUSION_EXECUTION_PARQUET_PUSHDOWN_FILTERS: "false"DATAFUSION_EXECUTION_PARQUET_REORDER_FILTERS: "false"changed:
ref: mainenv:
DATAFUSION_EXECUTION_PARQUET_PUSHDOWN_FILTERS: "true"DATAFUSION_EXECUTION_PARQUET_REORDER_FILTERS: "true" |
adriangb
commented
May 17, 2026
control: #21931 (comment) the goal is to see if this change makes turning pushdown on closer to good or not |
adriangbot
commented
May 17, 2026
🤖 Benchmark running (GKE) | trigger CPU Details (lscpu)Comparing HEAD (42adf29) to main diff using: tpch10 File an issue against this benchmark runner |
adriangbot
commented
May 17, 2026
🤖 Benchmark running (GKE) | trigger CPU Details (lscpu)Comparing main (47655fd) to main diff using: tpch10 File an issue against this benchmark runner |
adriangbot
commented
May 17, 2026
🤖 Benchmark completed (GKE) | trigger Instance: CPU Details (lscpu)DetailsResource Usagetpch10 — base (merge-base)
tpch10 — branch
File an issue against this benchmark runner |
adriangbot
commented
May 17, 2026
🤖 Benchmark completed (GKE) | trigger Instance: CPU Details (lscpu)DetailsResource Usagetpch10 — base (merge-base)
tpch10 — branch
File an issue against this benchmark runner |
adriangb
commented
May 17, 2026
Hmm those SF10 results aren’t great… |
gene-bordegaray
commented
May 18, 2026
The CPU utilization went up a good amount. Could it be better to have some threshold to only use the Or we could split and tune |
gene-bordegaray
commented
May 29, 2026
hey @adriangb are you still interested in this work. I would be willing to pick up and investigate this |
adriangb
commented
May 29, 2026
i am but i’m just strapped way too thin atm, if you can take a look would really appreciate it! |
gene-bordegaray
commented
May 30, 2026
@adriangb cool I will play around with it a bit and post updates here for you. No rush but just had this on queue of PRs 😄 |
Thank you for your contribution. Unfortunately, this pull request is stale because it has been open 60 days with no activity. Please remove the stale label or comment or this will be closed in 7 days. |
Which issue does this PR close?
Rationale for this change
Today the
Partitioned-modeHashJoinExecbuilds a dynamic filter that's structured around the repartition layout:Two problems with this:
hash_repartition % Neven though the partition's hash table will be probed anyway with a different seed (HASH_JOIN_SEED).This PR replaces the routing CASE with a structure that depends only on the content of the build side, not its layout, and adds a cross-partition merged `IN (SET)` fast path so small joins can participate in parquet stats / bloom-filter pruning at the scan side.
What changes are included in this PR?
Five commits:
Final filter-shape matrix
No more `CASE`, no more `hash_repartition`, no more `REPARTITION_RANDOM_STATE` in the dynamic-filter path.
Performance
Per-row cost (Partitioned mode)
Let `N` = number of build-side partitions. For each probe row evaluated by the dynamic filter:
Two countervailing forces shape the result:
Benchmarks (TPC-H, runner = c4a-highmem-16, ARM Neoverse-V2, 16 cores)
Triggered four runs covering both N regimes and both pushdown configs.
Default partitioning (N ≈ ncores ≈ 16)
In the `pushdown=true` run the wins concentrate on queries where the dynamic filter feeds parquet stats / bloom-filter pruning at the scan:
Q17 alone is 109 ms of the 93 ms total wall-clock improvement — that's the original issue's regression, fixed. The small-query regressions (Q3/Q5/Q9/Q13/Q14) are the all-Map shape paying `O(N)` probes per row for moderate-to-large build sides where the bounds prefix doesn't prune much.
High partition count (`target_partitions=128`)
A stress test of partition-count scaling on the same 16-core box.
Pushdown=false @ N=128: 11 queries faster, 0 slower, 11 unchanged. `multi_hash_lookup` cleanly beats the legacy 128-branch `CaseExpr` evaluation. Big wins on Q3 (1.68×), Q5 (1.82×), Q7 (1.75×), Q8 (2.15×), Q9 (1.64×), Q12 (1.81×), Q13 (1.76×), Q17 (1.59×), Q18 (1.29×), Q20 (2.05×), Q21 (1.43×).
Pushdown=true @ N=128: 4 faster, 9 slower. This is the case where the filter runs in the scan hot loop and `multi_hash_lookup`'s `O(N)` probes per row dominate. The wins (Q17 1.87×, Q18 1.39×, Q20 1.76×) survive because their merged `IN (SET)` prunes whole row groups before the per-row filter ever runs. The losses (Q5 1.88×, Q9 1.64×, Q21 1.62×, Q14 1.51×, Q8 1.37×) are the same all-Map shape paying 128 probes per row.
Summary of the regime grid
Three of the four configs are wins (one big), one is a regression. The single regressing config is `high N + scan-side pushdown`, which is exactly the scenario `OptionalFilterPhysicalExpr` from #20363 is designed to absorb: the adaptive tracker would measure `multi_hash_lookup`'s low `bytes_pruned_per_second_of_eval_time` for queries like Q5/Q9/Q21 and drop the filter, while keeping Q17/Q18/Q20 (which prune scans aggressively).
A possible structural follow-up — re-introducing partition routing inside `MultiMapLookupExpr` (1 routing hash + 1 probe, so per-row cost matches legacy CASE) — would close the regression at any N, with or without #20363.
Are these changes tested?
Are there any user-facing changes?
🤖 Generated with Claude Code