[vibebench] feat: implement GroupJoin optimization (Moerkotte & Neumann, VLDB 2011)#21015
[vibebench] feat: implement GroupJoin optimization (Moerkotte & Neumann, VLDB 2011)#21015Dandandan wants to merge 10 commits intoapache:mainfrom
Conversation
Fuses AggregateExec(Partial) on top of HashJoinExec into a single GroupJoinExec operator, avoiding materialization of the large intermediate join result when GROUP BY columns come from the left side and aggregate arguments come from the right side. GroupJoinExec builds a hash table on the right (build) side by collecting all right partitions, then for each left (probe) row looks up matches and accumulates them directly into GroupsAccumulators via the existing GroupValues machinery. The optimizer rule (`GroupJoinOptimization`) matches: - AggregateExec → HashJoinExec - AggregateExec → ProjectionExec → HashJoinExec Preconditions: INNER join only, no join filter, non-empty GROUP BY, no GROUPING SETS / DISTINCT / ORDER BY / per-agg FILTER, group-by refs left side, agg args ref right side. TPC-H Q12 now uses GroupJoinExec. All sqllogictest plan expectations updated accordingly. All query result tests pass. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
run benchmarks |
|
🤖 Benchmark completed (GKE) | trigger Details
Resource Usagetpch — base (merge-base)
tpch — branch
|
|
🤖 Benchmark completed (GKE) | trigger Details
Resource Usagetpcds — base (merge-base)
tpcds — branch
|
|
🤖 Benchmark completed (GKE) | trigger Details
Resource Usageclickbench_partitioned — base (merge-base)
clickbench_partitioned — branch
|
|
run benchmarks |
|
🤖 Benchmark completed (GKE) | trigger Details
Resource Usagetpch — base (merge-base)
tpch — branch
|
|
🤖 Benchmark completed (GKE) | trigger Details
Resource Usagetpcds — base (merge-base)
tpcds — branch
|
|
🤖 Benchmark completed (GKE) | trigger Details
Resource Usageclickbench_partitioned — base (merge-base)
clickbench_partitioned — branch
|
…rrays Two performance fixes for GroupJoinExec: 1. Build hash table on correct side: In CollectLeft mode, HashJoinExec builds on the LEFT (small) side, but GroupJoinExec builds on its RIGHT child. The optimizer now swaps inputs so GroupJoinExec.right = the original build side (small), fixing cases like TPC-H Q3 where a 200x larger hash table was being built on the wrong side. 2. Pre-compute build-side aggregate arrays: Previously, build-side aggregate argument expressions were re-evaluated on the entire build batch for every probe batch. Now they are evaluated once during collect_right_input() and stored in RightData. Also restricts GroupJoin to only match CollectLeft mode, since Partitioned mode has per-partition semantics incompatible with GroupJoinExec's collect-all-right behavior. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
run benchmarks |
|
🤖 Benchmark completed (GKE) | trigger Details
Resource Usageclickbench_partitioned — base (merge-base)
clickbench_partitioned — branch
|
|
run benchmarks |
|
🤖 Benchmark completed (GKE) | trigger Details
Resource Usageclickbench_partitioned — base (merge-base)
clickbench_partitioned — branch
|
|
run benchmarks |
- Skip all work for inner joins with empty build side (avoid evaluating group-by arrays) - Make matched_probe allocation and marking conditional on LEFT JOIN only - Persist probe/build index buffers across batches instead of re-allocating - Use compute::filter instead of index materialization in emit_unmatched_left_rows - Extract interleave_arrays helper to deduplicate 3 copies of the pattern - Remove unused _left_batch parameter from emit_unmatched_left_rows - Wire up baseline_metrics to record output rows Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
🤖 Benchmark completed (GKE) | trigger Details
Resource Usageclickbench_partitioned — base (merge-base)
clickbench_partitioned — branch
|
Fuses AggregateExec(Partial) on top of HashJoinExec into a single GroupJoinExec operator, avoiding materialization of the large intermediate join result when GROUP BY columns come from the left side and aggregate arguments come from the right side.
GroupJoinExec builds a hash table on the right (build) side by collecting all right partitions, then for each left (probe) row looks up matches and accumulates them directly into GroupsAccumulators via the existing GroupValues machinery.
The optimizer rule (
GroupJoinOptimization) matches:Preconditions: INNER join only, no join filter, non-empty GROUP BY, no GROUPING SETS / DISTINCT / ORDER BY / per-agg FILTER, group-by refs left side, agg args ref right side.
TPC-H Q12 now uses GroupJoinExec. All sqllogictest plan expectations updated accordingly. All query result tests pass.
Which issue does this PR close?
Rationale for this change
What changes are included in this PR?
Are these changes tested?
Are there any user-facing changes?