Skip to content

fix: Only apply SingleDistinctToGroupBy rewrite when it pays (closes #25932) - #26000

Open
mohitgurav20 wants to merge 33 commits into
apache:mainfrom
mohitgurav20:fix/single-distinct-groupby-memory-usage
Open

mohitgurav20 wants to merge 33 commits into
apache:mainfrom
mohitgurav20:fix/single-distinct-groupby-memory-usage

Conversation

@mohitgurav20

@mohitgurav20 mohitgurav20 commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Which issue does this PR close?

Closes #25932.

Rationale for this change

In queries with a single distinct aggregation, SingleDistinctToGroupBy rewrites the plan into a two-phase GROUP BY. As shown in benchmarks on #25932, this rewrite provides a ~2.5x speedup by enabling partition fan-out, but increases peak intermediate memory (~538–599 MiB vs ~306 MiB).

At the logical planning stage, statistics are not available to cost this trade-off automatically. This PR introduces an optimizer configuration knob so users can choose between maximum throughput (default) and lower peak memory when the system is under load.

What changes are included in this PR?

  • Added datafusion.optimizer.single_distinct_aggregation_prefer_memory: bool (default false).
  • Default (false): Preserves the existing behavior for lone distinct queries—rewriting into two-phase GROUP BY to maintain throughput and partition parallelism.
  • Opt-in (true): Gated by rewrite_pays; skips the two-phase rewrite if the distinct aggregate function already supports GroupsAccumulator, reducing intermediate memory usage.
  • Correctness invariant: Aggregates with DistinctHandling::Unsupported (such as approx_median) still rewrite unconditionally to guarantee correct execution.
  • Added unit tests in single_distinct_to_groupby.rs, end-to-end EXPLAIN and execution coverage in single_distinct_to_groupby.slt, updated information_schema.slt, and updated config documentation.

Are these changes tested?

Yes:

  • Unit tests covering both flag states (prefer_memory = false and prefer_memory = true) and unsupported distinct fallbacks.
  • Sqllogictests for plan inspection (EXPLAIN) and query execution.
  • Full local CI pre-checks passed (cargo fmt, cargo clippy -D warnings, and optimizer test suite).

Are there any user-facing changes?

Yes:

  • Added configuration option datafusion.optimizer.single_distinct_aggregation_prefer_memory.

@github-actions github-actions Bot added the optimizer Optimizer rules label Oct 3, 2026
@mohitgurav20
mohitgurav20 force-pushed the fix/single-distinct-groupby-memory-usage branch from 527a544 to 9e8dfe6 Compare October 4, 2026 16:36
@github-actions github-actions Bot added the core Core DataFusion crate label Oct 4, 2026

@mkleen mkleen 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.

@mohitgurav20 Thanks for working on this.
Can you make sure all sql-logic tests pass, or correct them if invalid.
You can run them locally with:

cargo test --profile=ci --test sqllogictests

@github-actions github-actions Bot added the sqllogictest SQL Logic Tests (.slt) label Oct 9, 2026
@codecov-commenter

codecov-commenter commented Oct 10, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 87.53541% with 44 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.94%. Comparing base (3ee3e39) to head (38468c5).
⚠️ Report is 29 commits behind head on main.

Files with missing lines Patch % Lines
...fusion/optimizer/src/single_distinct_to_groupby.rs 87.50% 3 Missing and 41 partials ⚠️
Additional details and impacted files
@@           Coverage Diff            @@
##             main   #26000    +/-   ##
========================================
  Coverage   82.93%   82.94%            
========================================
  Files        1154     1154            
  Lines      458002   458300   +298     
  Branches   458002   458300   +298     
========================================
+ Hits       379856   380130   +274     
+ Misses      55123    55104    -19     
- Partials    23023    23066    +43     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@mohitgurav20
mohitgurav20 force-pushed the fix/single-distinct-groupby-memory-usage branch from 63e9873 to 0c76607 Compare October 10, 2026 19:06
@mohitgurav20
mohitgurav20 requested a review from mkleen October 11, 2026 05:11
@mohitgurav20

Copy link
Copy Markdown
Contributor Author

@mkleen sir i have completed the work and addressed ur suggestion pls feel free to review and would like to work if any changes needed.

@mkleen

mkleen commented Oct 11, 2026

Copy link
Copy Markdown
Contributor

run benchmarks

@adriangbot

Copy link
Copy Markdown

🤖 Benchmark running (GKE) | trigger
Instance: c4a-highmem-16 (12 vCPU / 65 GiB) | Linux bench-c6114216591-3306-6nkh2 6.12.94+ #1 SMP Fri Aug 21 08:00:16 UTC 2026 aarch64 GNU/Linux

CPU Details (lscpu)
Architecture:                            aarch64
CPU op-mode(s):                          64-bit
Byte Order:                              Little Endian
CPU(s):                                  16
On-line CPU(s) list:                     0-15
Vendor ID:                               ARM
Model name:                              Neoverse-V2
Model:                                   1
Thread(s) per core:                      1
Core(s) per cluster:                     16
Socket(s):                               -
Cluster(s):                              1
Stepping:                                r0p1
BogoMIPS:                                2000.00
Flags:                                   fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 sm3 sm4 asimddp sha512 sve asimdfhm dit uscat ilrcpc flagm sb paca pacg dcpodp sve2 sveaes svepmull svebitperm svesha3 svesm4 flagm2 frint svei8mm svebf16 i8mm bf16 dgh rng bti
L1d cache:                               1 MiB (16 instances)
L1i cache:                               1 MiB (16 instances)
L2 cache:                                32 MiB (16 instances)
L3 cache:                                80 MiB (1 instance)
NUMA node(s):                            1
NUMA node0 CPU(s):                       0-15
Vulnerability Gather data sampling:      Not affected
Vulnerability Indirect target selection: Not affected
Vulnerability Itlb multihit:             Not affected
Vulnerability L1tf:                      Not affected
Vulnerability Mds:                       Not affected
Vulnerability Meltdown:                  Not affected
Vulnerability Mmio stale data:           Not affected
Vulnerability Reg file data sampling:    Not affected
Vulnerability Retbleed:                  Not affected
Vulnerability Spec rstack overflow:      Not affected
Vulnerability Spec store bypass:         Mitigation; Speculative Store Bypass disabled via prctl
Vulnerability Spectre v1:                Mitigation; __user pointer sanitization
Vulnerability Spectre v2:                Mitigation; CSV2, BHB
Vulnerability Srbds:                     Not affected
Vulnerability Tsa:                       Not affected
Vulnerability Tsx async abort:           Not affected
Vulnerability Vmscape:                   Not affected

Comparing fix/single-distinct-groupby-memory-usage (0923424) to 334f293 (merge-base) diff

Run configuration
run benchmark clickbench_partitioned

Results will be posted here when complete


File an issue against this benchmark runner

@adriangbot

Copy link
Copy Markdown

🤖 Benchmark running (GKE) | trigger
Instance: c4a-highmem-16 (12 vCPU / 65 GiB) | Linux bench-c6114216591-3307-dzrvx 6.12.94+ #1 SMP Fri Aug 21 08:00:16 UTC 2026 aarch64 GNU/Linux

CPU Details (lscpu)
Architecture:                            aarch64
CPU op-mode(s):                          64-bit
Byte Order:                              Little Endian
CPU(s):                                  16
On-line CPU(s) list:                     0-15
Vendor ID:                               ARM
Model name:                              Neoverse-V2
Model:                                   1
Thread(s) per core:                      1
Core(s) per cluster:                     16
Socket(s):                               -
Cluster(s):                              1
Stepping:                                r0p1
BogoMIPS:                                2000.00
Flags:                                   fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 sm3 sm4 asimddp sha512 sve asimdfhm dit uscat ilrcpc flagm sb paca pacg dcpodp sve2 sveaes svepmull svebitperm svesha3 svesm4 flagm2 frint svei8mm svebf16 i8mm bf16 dgh rng bti
L1d cache:                               1 MiB (16 instances)
L1i cache:                               1 MiB (16 instances)
L2 cache:                                32 MiB (16 instances)
L3 cache:                                80 MiB (1 instance)
NUMA node(s):                            1
NUMA node0 CPU(s):                       0-15
Vulnerability Gather data sampling:      Not affected
Vulnerability Indirect target selection: Not affected
Vulnerability Itlb multihit:             Not affected
Vulnerability L1tf:                      Not affected
Vulnerability Mds:                       Not affected
Vulnerability Meltdown:                  Not affected
Vulnerability Mmio stale data:           Not affected
Vulnerability Reg file data sampling:    Not affected
Vulnerability Retbleed:                  Not affected
Vulnerability Spec rstack overflow:      Not affected
Vulnerability Spec store bypass:         Mitigation; Speculative Store Bypass disabled via prctl
Vulnerability Spectre v1:                Mitigation; __user pointer sanitization
Vulnerability Spectre v2:                Mitigation; CSV2, BHB
Vulnerability Srbds:                     Not affected
Vulnerability Tsa:                       Not affected
Vulnerability Tsx async abort:           Not affected
Vulnerability Vmscape:                   Not affected

Comparing fix/single-distinct-groupby-memory-usage (0923424) to 334f293 (merge-base) diff

Run configuration
run benchmark tpcds

Results will be posted here when complete


File an issue against this benchmark runner

@adriangbot

Copy link
Copy Markdown

🤖 Benchmark running (GKE) | trigger
Instance: c4a-highmem-16 (12 vCPU / 65 GiB) | Linux bench-c6114216591-3308-fcbjc 6.12.94+ #1 SMP Fri Aug 21 08:00:16 UTC 2026 aarch64 GNU/Linux

CPU Details (lscpu)
Architecture:                            aarch64
CPU op-mode(s):                          64-bit
Byte Order:                              Little Endian
CPU(s):                                  16
On-line CPU(s) list:                     0-15
Vendor ID:                               ARM
Model name:                              Neoverse-V2
Model:                                   1
Thread(s) per core:                      1
Core(s) per cluster:                     16
Socket(s):                               -
Cluster(s):                              1
Stepping:                                r0p1
BogoMIPS:                                2000.00
Flags:                                   fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 sm3 sm4 asimddp sha512 sve asimdfhm dit uscat ilrcpc flagm sb paca pacg dcpodp sve2 sveaes svepmull svebitperm svesha3 svesm4 flagm2 frint svei8mm svebf16 i8mm bf16 dgh rng bti
L1d cache:                               1 MiB (16 instances)
L1i cache:                               1 MiB (16 instances)
L2 cache:                                32 MiB (16 instances)
L3 cache:                                80 MiB (1 instance)
NUMA node(s):                            1
NUMA node0 CPU(s):                       0-15
Vulnerability Gather data sampling:      Not affected
Vulnerability Indirect target selection: Not affected
Vulnerability Itlb multihit:             Not affected
Vulnerability L1tf:                      Not affected
Vulnerability Mds:                       Not affected
Vulnerability Meltdown:                  Not affected
Vulnerability Mmio stale data:           Not affected
Vulnerability Reg file data sampling:    Not affected
Vulnerability Retbleed:                  Not affected
Vulnerability Spec rstack overflow:      Not affected
Vulnerability Spec store bypass:         Mitigation; Speculative Store Bypass disabled via prctl
Vulnerability Spectre v1:                Mitigation; __user pointer sanitization
Vulnerability Spectre v2:                Mitigation; CSV2, BHB
Vulnerability Srbds:                     Not affected
Vulnerability Tsa:                       Not affected
Vulnerability Tsx async abort:           Not affected
Vulnerability Vmscape:                   Not affected

Comparing fix/single-distinct-groupby-memory-usage (0923424) to 334f293 (merge-base) diff

Run configuration
run benchmark tpch

Results will be posted here when complete


File an issue against this benchmark runner

@adriangbot

Copy link
Copy Markdown

🤖 Benchmark completed (GKE) | trigger

Instance: c4a-highmem-16 (12 vCPU / 65 GiB)

Comparing fix/single-distinct-groupby-memory-usage (0923424) to 334f293 (merge-base) diff

Run configuration
run benchmark tpch
CPU Details (lscpu)
Architecture:                            aarch64
CPU op-mode(s):                          64-bit
Byte Order:                              Little Endian
CPU(s):                                  16
On-line CPU(s) list:                     0-15
Vendor ID:                               ARM
Model name:                              Neoverse-V2
Model:                                   1
Thread(s) per core:                      1
Core(s) per cluster:                     16
Socket(s):                               -
Cluster(s):                              1
Stepping:                                r0p1
BogoMIPS:                                2000.00
Flags:                                   fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 sm3 sm4 asimddp sha512 sve asimdfhm dit uscat ilrcpc flagm sb paca pacg dcpodp sve2 sveaes svepmull svebitperm svesha3 svesm4 flagm2 frint svei8mm svebf16 i8mm bf16 dgh rng bti
L1d cache:                               1 MiB (16 instances)
L1i cache:                               1 MiB (16 instances)
L2 cache:                                32 MiB (16 instances)
L3 cache:                                80 MiB (1 instance)
NUMA node(s):                            1
NUMA node0 CPU(s):                       0-15
Vulnerability Gather data sampling:      Not affected
Vulnerability Indirect target selection: Not affected
Vulnerability Itlb multihit:             Not affected
Vulnerability L1tf:                      Not affected
Vulnerability Mds:                       Not affected
Vulnerability Meltdown:                  Not affected
Vulnerability Mmio stale data:           Not affected
Vulnerability Reg file data sampling:    Not affected
Vulnerability Retbleed:                  Not affected
Vulnerability Spec rstack overflow:      Not affected
Vulnerability Spec store bypass:         Mitigation; Speculative Store Bypass disabled via prctl
Vulnerability Spectre v1:                Mitigation; __user pointer sanitization
Vulnerability Spectre v2:                Mitigation; CSV2, BHB
Vulnerability Srbds:                     Not affected
Vulnerability Tsa:                       Not affected
Vulnerability Tsx async abort:           Not affected
Vulnerability Vmscape:                   Not affected
Details

Comparing HEAD and fix_single-distinct-groupby-memory-usage
--------------------
Benchmark tpch_sf1.json
--------------------
┏━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Query     ┃     HEAD ┃ fix_single-distinct-groupby-memory-usage ┃        Change ┃
┡━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ QQuery 1  │ 40.29 ms │                                 40.32 ms │     no change │
│ QQuery 2  │ 18.13 ms │                                 18.16 ms │     no change │
│ QQuery 3  │ 28.23 ms │                                 28.28 ms │     no change │
│ QQuery 4  │ 17.14 ms │                                 17.06 ms │     no change │
│ QQuery 5  │ 35.12 ms │                                 35.57 ms │     no change │
│ QQuery 6  │ 13.35 ms │                                 13.56 ms │     no change │
│ QQuery 7  │ 42.15 ms │                                 41.29 ms │     no change │
│ QQuery 8  │ 40.83 ms │                                 41.29 ms │     no change │
│ QQuery 9  │ 50.50 ms │                                 50.92 ms │     no change │
│ QQuery 10 │ 40.28 ms │                                 40.46 ms │     no change │
│ QQuery 11 │ 13.26 ms │                                 13.27 ms │     no change │
│ QQuery 12 │ 18.03 ms │                                 18.43 ms │     no change │
│ QQuery 13 │ 39.16 ms │                                 38.90 ms │     no change │
│ QQuery 14 │ 24.47 ms │                                 24.44 ms │     no change │
│ QQuery 15 │ 30.29 ms │                                 30.73 ms │     no change │
│ QQuery 16 │ 13.63 ms │                                 11.66 ms │ +1.17x faster │
│ QQuery 17 │ 73.99 ms │                                 73.56 ms │     no change │
│ QQuery 18 │ 45.29 ms │                                 45.11 ms │     no change │
│ QQuery 19 │ 31.51 ms │                                 31.65 ms │     no change │
│ QQuery 20 │ 31.36 ms │                                 31.67 ms │     no change │
│ QQuery 21 │ 54.39 ms │                                 54.99 ms │     no change │
│ QQuery 22 │ 13.54 ms │                                 13.63 ms │     no change │
└───────────┴──────────┴──────────────────────────────────────────┴───────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┓
┃ Benchmark Summary                                       ┃          ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━┩
│ Total Time (HEAD)                                       │ 714.94ms │
│ Total Time (fix_single-distinct-groupby-memory-usage)   │ 714.93ms │
│ Average Time (HEAD)                                     │  32.50ms │
│ Average Time (fix_single-distinct-groupby-memory-usage) │  32.50ms │
│ Queries Faster                                          │        1 │
│ Queries Slower                                          │        0 │
│ Queries with No Change                                  │       21 │
│ Queries with Failure                                    │        0 │
└─────────────────────────────────────────────────────────┴──────────┘

Distribution per query (min / mean ±stddev / max):

Comparing HEAD and fix_single-distinct-groupby-memory-usage
--------------------
Benchmark tpch_sf1.json
--------------------
┏━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Query     ┃                           HEAD ┃ fix_single-distinct-groupby-memory-usage ┃        Change ┃
┡━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ QQuery 1  │ 40.29 / 40.97 ±1.06 / 43.07 ms │           40.32 / 41.00 ±0.96 / 42.90 ms │     no change │
│ QQuery 2  │ 18.13 / 18.38 ±0.33 / 18.98 ms │           18.16 / 18.50 ±0.29 / 18.98 ms │     no change │
│ QQuery 3  │ 28.23 / 28.63 ±0.30 / 29.12 ms │           28.28 / 28.61 ±0.23 / 28.91 ms │     no change │
│ QQuery 4  │ 17.14 / 17.56 ±0.60 / 18.74 ms │           17.06 / 17.30 ±0.19 / 17.62 ms │     no change │
│ QQuery 5  │ 35.12 / 36.10 ±1.42 / 38.90 ms │           35.57 / 35.67 ±0.07 / 35.80 ms │     no change │
│ QQuery 6  │ 13.35 / 13.81 ±0.56 / 14.90 ms │           13.56 / 14.42 ±0.87 / 15.93 ms │     no change │
│ QQuery 7  │ 42.15 / 42.74 ±0.69 / 43.78 ms │           41.29 / 43.01 ±1.29 / 44.83 ms │     no change │
│ QQuery 8  │ 40.83 / 42.21 ±2.10 / 46.38 ms │           41.29 / 42.71 ±2.33 / 47.35 ms │     no change │
│ QQuery 9  │ 50.50 / 51.06 ±0.54 / 51.88 ms │           50.92 / 51.07 ±0.17 / 51.38 ms │     no change │
│ QQuery 10 │ 40.28 / 42.76 ±3.92 / 50.57 ms │           40.46 / 40.79 ±0.21 / 41.11 ms │     no change │
│ QQuery 11 │ 13.26 / 13.65 ±0.36 / 14.27 ms │           13.27 / 13.77 ±0.65 / 15.05 ms │     no change │
│ QQuery 12 │ 18.03 / 18.38 ±0.34 / 19.02 ms │           18.43 / 18.66 ±0.17 / 18.90 ms │     no change │
│ QQuery 13 │ 39.16 / 39.35 ±0.10 / 39.43 ms │           38.90 / 39.73 ±1.25 / 42.18 ms │     no change │
│ QQuery 14 │ 24.47 / 24.61 ±0.08 / 24.69 ms │           24.44 / 24.54 ±0.09 / 24.69 ms │     no change │
│ QQuery 15 │ 30.29 / 30.71 ±0.32 / 31.22 ms │           30.73 / 31.08 ±0.35 / 31.72 ms │     no change │
│ QQuery 16 │ 13.63 / 13.87 ±0.15 / 14.10 ms │           11.66 / 12.02 ±0.22 / 12.31 ms │ +1.15x faster │
│ QQuery 17 │ 73.99 / 74.37 ±0.23 / 74.61 ms │           73.56 / 74.20 ±0.38 / 74.60 ms │     no change │
│ QQuery 18 │ 45.29 / 45.54 ±0.21 / 45.89 ms │           45.11 / 46.05 ±0.96 / 47.78 ms │     no change │
│ QQuery 19 │ 31.51 / 31.91 ±0.34 / 32.51 ms │           31.65 / 33.01 ±1.31 / 35.23 ms │     no change │
│ QQuery 20 │ 31.36 / 31.78 ±0.46 / 32.62 ms │           31.67 / 31.92 ±0.26 / 32.39 ms │     no change │
│ QQuery 21 │ 54.39 / 55.74 ±1.66 / 58.89 ms │           54.99 / 56.49 ±0.98 / 57.55 ms │     no change │
│ QQuery 22 │ 13.54 / 13.71 ±0.13 / 13.91 ms │           13.63 / 13.91 ±0.22 / 14.16 ms │     no change │
└───────────┴────────────────────────────────┴──────────────────────────────────────────┴───────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┓
┃ Benchmark Summary                                       ┃          ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━┩
│ Total Time (HEAD)                                       │ 727.85ms │
│ Total Time (fix_single-distinct-groupby-memory-usage)   │ 728.44ms │
│ Average Time (HEAD)                                     │  33.08ms │
│ Average Time (fix_single-distinct-groupby-memory-usage) │  33.11ms │
│ Queries Faster                                          │        1 │
│ Queries Slower                                          │        0 │
│ Queries with No Change                                  │       21 │
│ Queries with Failure                                    │        0 │
└─────────────────────────────────────────────────────────┴──────────┘

Resource Usage

tpch — base (merge-base)

Metric Value
Wall time 5.0s
Peak memory 1.1 GiB
Avg memory 473.9 MiB
CPU user 19.8s
CPU sys 1.7s
Peak spill 0 B

tpch — branch

Metric Value
Wall time 5.0s
Peak memory 1.1 GiB
Avg memory 478.5 MiB
CPU user 19.9s
CPU sys 1.6s
Peak spill 0 B

File an issue against this benchmark runner

@adriangbot

Copy link
Copy Markdown

🤖 Benchmark completed (GKE) | trigger

Instance: c4a-highmem-16 (12 vCPU / 65 GiB)

Comparing fix/single-distinct-groupby-memory-usage (0923424) to 334f293 (merge-base) diff

Run configuration
run benchmark tpcds
CPU Details (lscpu)
Architecture:                            aarch64
CPU op-mode(s):                          64-bit
Byte Order:                              Little Endian
CPU(s):                                  16
On-line CPU(s) list:                     0-15
Vendor ID:                               ARM
Model name:                              Neoverse-V2
Model:                                   1
Thread(s) per core:                      1
Core(s) per cluster:                     16
Socket(s):                               -
Cluster(s):                              1
Stepping:                                r0p1
BogoMIPS:                                2000.00
Flags:                                   fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 sm3 sm4 asimddp sha512 sve asimdfhm dit uscat ilrcpc flagm sb paca pacg dcpodp sve2 sveaes svepmull svebitperm svesha3 svesm4 flagm2 frint svei8mm svebf16 i8mm bf16 dgh rng bti
L1d cache:                               1 MiB (16 instances)
L1i cache:                               1 MiB (16 instances)
L2 cache:                                32 MiB (16 instances)
L3 cache:                                80 MiB (1 instance)
NUMA node(s):                            1
NUMA node0 CPU(s):                       0-15
Vulnerability Gather data sampling:      Not affected
Vulnerability Indirect target selection: Not affected
Vulnerability Itlb multihit:             Not affected
Vulnerability L1tf:                      Not affected
Vulnerability Mds:                       Not affected
Vulnerability Meltdown:                  Not affected
Vulnerability Mmio stale data:           Not affected
Vulnerability Reg file data sampling:    Not affected
Vulnerability Retbleed:                  Not affected
Vulnerability Spec rstack overflow:      Not affected
Vulnerability Spec store bypass:         Mitigation; Speculative Store Bypass disabled via prctl
Vulnerability Spectre v1:                Mitigation; __user pointer sanitization
Vulnerability Spectre v2:                Mitigation; CSV2, BHB
Vulnerability Srbds:                     Not affected
Vulnerability Tsa:                       Not affected
Vulnerability Tsx async abort:           Not affected
Vulnerability Vmscape:                   Not affected
Details

Comparing HEAD and fix_single-distinct-groupby-memory-usage
--------------------
Benchmark tpcds_sf1.json
--------------------
┏━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Query     ┃       HEAD ┃ fix_single-distinct-groupby-memory-usage ┃        Change ┃
┡━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ QQuery 1  │    5.42 ms │                                  5.48 ms │     no change │
│ QQuery 2  │   79.52 ms │                                 79.63 ms │     no change │
│ QQuery 3  │   28.07 ms │                                 28.11 ms │     no change │
│ QQuery 4  │  428.64 ms │                                427.69 ms │     no change │
│ QQuery 5  │   49.27 ms │                                 49.56 ms │     no change │
│ QQuery 6  │   34.13 ms │                                 34.40 ms │     no change │
│ QQuery 7  │   71.83 ms │                                 71.95 ms │     no change │
│ QQuery 8  │   35.53 ms │                                 35.81 ms │     no change │
│ QQuery 9  │   50.74 ms │                                 50.77 ms │     no change │
│ QQuery 10 │   61.74 ms │                                 61.42 ms │     no change │
│ QQuery 11 │  261.04 ms │                                264.22 ms │     no change │
│ QQuery 12 │   28.34 ms │                                 28.31 ms │     no change │
│ QQuery 13 │  111.88 ms │                                111.92 ms │     no change │
│ QQuery 14 │  382.80 ms │                                380.70 ms │     no change │
│ QQuery 15 │   51.27 ms │                                 52.04 ms │     no change │
│ QQuery 16 │    6.20 ms │                                  5.51 ms │ +1.12x faster │
│ QQuery 17 │   78.98 ms │                                 77.83 ms │     no change │
│ QQuery 18 │  102.77 ms │                                103.49 ms │     no change │
│ QQuery 19 │   40.90 ms │                                 40.78 ms │     no change │
│ QQuery 20 │   35.30 ms │                                 35.07 ms │     no change │
│ QQuery 21 │   16.52 ms │                                 16.40 ms │     no change │
│ QQuery 22 │   62.15 ms │                                 62.80 ms │     no change │
│ QQuery 23 │  299.29 ms │                                299.83 ms │     no change │
│ QQuery 24 │  189.60 ms │                                189.43 ms │     no change │
│ QQuery 25 │  107.82 ms │                                106.95 ms │     no change │
│ QQuery 26 │   45.49 ms │                                 45.27 ms │     no change │
│ QQuery 27 │    5.79 ms │                                  5.81 ms │     no change │
│ QQuery 28 │   55.00 ms │                                 60.08 ms │  1.09x slower │
│ QQuery 29 │   94.14 ms │                                 95.50 ms │     no change │
│ QQuery 30 │   32.64 ms │                                 31.94 ms │     no change │
│ QQuery 31 │  105.84 ms │                                107.09 ms │     no change │
│ QQuery 32 │   20.02 ms │                                 19.43 ms │     no change │
│ QQuery 33 │   35.91 ms │                                 36.15 ms │     no change │
│ QQuery 34 │    9.69 ms │                                  9.76 ms │     no change │
│ QQuery 35 │   70.62 ms │                                 70.50 ms │     no change │
│ QQuery 36 │    5.51 ms │                                  5.43 ms │     no change │
│ QQuery 37 │    6.57 ms │                                  6.52 ms │     no change │
│ QQuery 38 │   60.02 ms │                                 59.40 ms │     no change │
│ QQuery 39 │   71.53 ms │                                 71.64 ms │     no change │
│ QQuery 40 │   23.38 ms │                                 22.17 ms │ +1.05x faster │
│ QQuery 41 │   10.97 ms │                                 11.04 ms │     no change │
│ QQuery 42 │   22.91 ms │                                 22.91 ms │     no change │
│ QQuery 43 │    4.63 ms │                                  4.69 ms │     no change │
│ QQuery 44 │    8.50 ms │                                  8.59 ms │     no change │
│ QQuery 45 │   35.60 ms │                                 35.13 ms │     no change │
│ QQuery 46 │   11.45 ms │                                 11.43 ms │     no change │
│ QQuery 47 │  214.57 ms │                                215.34 ms │     no change │
│ QQuery 48 │   90.01 ms │                                 89.35 ms │     no change │
│ QQuery 49 │   68.33 ms │                                 68.31 ms │     no change │
│ QQuery 50 │   58.02 ms │                                 57.54 ms │     no change │
│ QQuery 51 │   92.75 ms │                                 91.56 ms │     no change │
│ QQuery 52 │   23.21 ms │                                 23.49 ms │     no change │
│ QQuery 53 │   28.69 ms │                                 28.84 ms │     no change │
│ QQuery 54 │   52.63 ms │                                 52.30 ms │     no change │
│ QQuery 55 │   22.69 ms │                                 22.85 ms │     no change │
│ QQuery 56 │   36.60 ms │                                 37.39 ms │     no change │
│ QQuery 57 │  165.20 ms │                                164.97 ms │     no change │
│ QQuery 58 │  106.04 ms │                                105.01 ms │     no change │
│ QQuery 59 │  114.61 ms │                                113.98 ms │     no change │
│ QQuery 60 │   37.64 ms │                                 37.96 ms │     no change │
│ QQuery 61 │   10.79 ms │                                 10.84 ms │     no change │
│ QQuery 62 │   42.55 ms │                                 42.82 ms │     no change │
│ QQuery 63 │   28.77 ms │                                 28.52 ms │     no change │
│ QQuery 64 │  356.97 ms │                                359.36 ms │     no change │
│ QQuery 65 │  126.65 ms │                                130.29 ms │     no change │
│ QQuery 66 │   74.08 ms │                                 74.02 ms │     no change │
│ QQuery 67 │  241.97 ms │                                244.49 ms │     no change │
│ QQuery 68 │   11.64 ms │                                 11.58 ms │     no change │
│ QQuery 69 │   56.34 ms │                                 55.62 ms │     no change │
│ QQuery 70 │  102.86 ms │                                102.13 ms │     no change │
│ QQuery 71 │   34.36 ms │                                 34.06 ms │     no change │
│ QQuery 72 │ 1561.27 ms │                               1516.53 ms │     no change │
│ QQuery 73 │    9.63 ms │                                  9.60 ms │     no change │
│ QQuery 74 │  154.31 ms │                                150.74 ms │     no change │
│ QQuery 75 │  138.10 ms │                                139.11 ms │     no change │
│ QQuery 76 │   33.01 ms │                                 34.15 ms │     no change │
│ QQuery 77 │   59.29 ms │                                 59.03 ms │     no change │
│ QQuery 78 │  158.53 ms │                                157.71 ms │     no change │
│ QQuery 79 │   65.74 ms │                                 65.46 ms │     no change │
│ QQuery 80 │   93.20 ms │                                 93.85 ms │     no change │
│ QQuery 81 │   25.50 ms │                                 25.44 ms │     no change │
│ QQuery 82 │   16.23 ms │                                 16.15 ms │     no change │
│ QQuery 83 │   32.69 ms │                                 32.19 ms │     no change │
│ QQuery 84 │   29.18 ms │                                 29.26 ms │     no change │
│ QQuery 85 │   97.46 ms │                                 97.39 ms │     no change │
│ QQuery 86 │   24.72 ms │                                 24.81 ms │     no change │
│ QQuery 87 │   59.74 ms │                                 59.54 ms │     no change │
│ QQuery 88 │   59.18 ms │                                 58.74 ms │     no change │
│ QQuery 89 │   34.50 ms │                                 34.39 ms │     no change │
│ QQuery 90 │   16.12 ms │                                 15.94 ms │     no change │
│ QQuery 91 │   40.03 ms │                                 40.47 ms │     no change │
│ QQuery 92 │   28.54 ms │                                 29.21 ms │     no change │
│ QQuery 93 │   48.37 ms │                                 48.81 ms │     no change │
│ QQuery 94 │   37.39 ms │                                 36.85 ms │     no change │
│ QQuery 95 │   78.35 ms │                                 78.76 ms │     no change │
│ QQuery 96 │   23.04 ms │                                 23.29 ms │     no change │
│ QQuery 97 │   49.44 ms │                                 51.90 ms │     no change │
│ QQuery 98 │   41.95 ms │                                 41.46 ms │     no change │
│ QQuery 99 │   63.69 ms │                                 63.86 ms │     no change │
└───────────┴────────────┴──────────────────────────────────────────┴───────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━┓
┃ Benchmark Summary                                       ┃           ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━┩
│ Total Time (HEAD)                                       │ 8633.14ms │
│ Total Time (fix_single-distinct-groupby-memory-usage)   │ 8597.84ms │
│ Average Time (HEAD)                                     │   87.20ms │
│ Average Time (fix_single-distinct-groupby-memory-usage) │   86.85ms │
│ Queries Faster                                          │         2 │
│ Queries Slower                                          │         1 │
│ Queries with No Change                                  │        96 │
│ Queries with Failure                                    │         0 │
└─────────────────────────────────────────────────────────┴───────────┘

Distribution per query (min / mean ±stddev / max):

Comparing HEAD and fix_single-distinct-groupby-memory-usage
--------------------
Benchmark tpcds_sf1.json
--------------------
┏━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Query     ┃                                  HEAD ┃ fix_single-distinct-groupby-memory-usage ┃        Change ┃
┡━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ QQuery 1  │           5.42 / 6.02 ±1.02 / 8.03 ms │              5.48 / 6.06 ±1.02 / 8.11 ms │     no change │
│ QQuery 2  │        79.52 / 79.71 ±0.21 / 80.11 ms │           79.63 / 80.03 ±0.34 / 80.43 ms │     no change │
│ QQuery 3  │        28.07 / 28.39 ±0.26 / 28.86 ms │           28.11 / 28.37 ±0.19 / 28.66 ms │     no change │
│ QQuery 4  │     428.64 / 431.52 ±1.89 / 434.03 ms │        427.69 / 433.05 ±4.37 / 439.07 ms │     no change │
│ QQuery 5  │        49.27 / 49.96 ±0.57 / 50.80 ms │           49.56 / 50.02 ±0.37 / 50.58 ms │     no change │
│ QQuery 6  │        34.13 / 35.29 ±0.87 / 36.77 ms │           34.40 / 36.33 ±2.59 / 41.42 ms │     no change │
│ QQuery 7  │        71.83 / 72.61 ±0.57 / 73.12 ms │           71.95 / 73.18 ±1.02 / 74.37 ms │     no change │
│ QQuery 8  │        35.53 / 35.89 ±0.29 / 36.35 ms │           35.81 / 36.36 ±0.46 / 37.17 ms │     no change │
│ QQuery 9  │        50.74 / 52.83 ±1.23 / 54.18 ms │           50.77 / 53.35 ±2.21 / 56.93 ms │     no change │
│ QQuery 10 │        61.74 / 63.30 ±2.27 / 67.81 ms │           61.42 / 63.43 ±2.99 / 69.39 ms │     no change │
│ QQuery 11 │     261.04 / 265.30 ±3.46 / 271.25 ms │        264.22 / 268.31 ±2.64 / 272.49 ms │     no change │
│ QQuery 12 │        28.34 / 28.94 ±0.40 / 29.43 ms │           28.31 / 28.70 ±0.30 / 29.12 ms │     no change │
│ QQuery 13 │     111.88 / 112.90 ±0.96 / 114.71 ms │        111.92 / 114.06 ±1.42 / 116.11 ms │     no change │
│ QQuery 14 │     382.80 / 389.27 ±4.06 / 394.08 ms │        380.70 / 384.02 ±2.43 / 387.26 ms │     no change │
│ QQuery 15 │        51.27 / 53.59 ±2.80 / 59.08 ms │           52.04 / 53.58 ±1.45 / 56.30 ms │     no change │
│ QQuery 16 │           6.20 / 6.31 ±0.18 / 6.66 ms │              5.51 / 5.68 ±0.20 / 6.07 ms │ +1.11x faster │
│ QQuery 17 │        78.98 / 79.41 ±0.40 / 79.98 ms │           77.83 / 78.07 ±0.16 / 78.27 ms │     no change │
│ QQuery 18 │     102.77 / 105.49 ±2.54 / 110.29 ms │        103.49 / 104.86 ±1.32 / 107.35 ms │     no change │
│ QQuery 19 │        40.90 / 41.33 ±0.37 / 41.84 ms │           40.78 / 41.04 ±0.18 / 41.23 ms │     no change │
│ QQuery 20 │        35.30 / 35.94 ±0.67 / 36.87 ms │           35.07 / 35.18 ±0.11 / 35.36 ms │     no change │
│ QQuery 21 │        16.52 / 17.33 ±1.26 / 19.83 ms │           16.40 / 17.31 ±1.04 / 19.27 ms │     no change │
│ QQuery 22 │        62.15 / 62.84 ±0.39 / 63.30 ms │           62.80 / 63.15 ±0.30 / 63.62 ms │     no change │
│ QQuery 23 │     299.29 / 304.57 ±4.68 / 311.02 ms │        299.83 / 302.09 ±2.39 / 306.19 ms │     no change │
│ QQuery 24 │     189.60 / 194.38 ±5.91 / 205.90 ms │        189.43 / 193.47 ±4.36 / 201.89 ms │     no change │
│ QQuery 25 │     107.82 / 109.31 ±1.21 / 110.79 ms │        106.95 / 108.29 ±1.29 / 110.07 ms │     no change │
│ QQuery 26 │        45.49 / 47.45 ±2.63 / 52.65 ms │           45.27 / 47.49 ±2.88 / 53.11 ms │     no change │
│ QQuery 27 │           5.79 / 6.03 ±0.25 / 6.51 ms │              5.81 / 6.06 ±0.26 / 6.49 ms │     no change │
│ QQuery 28 │        55.00 / 57.61 ±2.18 / 60.97 ms │           60.08 / 60.53 ±0.36 / 60.97 ms │  1.05x slower │
│ QQuery 29 │        94.14 / 95.80 ±1.33 / 98.00 ms │           95.50 / 96.48 ±1.40 / 99.15 ms │     no change │
│ QQuery 30 │        32.64 / 34.26 ±2.09 / 38.34 ms │           31.94 / 33.76 ±2.70 / 39.12 ms │     no change │
│ QQuery 31 │     105.84 / 107.20 ±1.27 / 109.59 ms │        107.09 / 107.88 ±0.86 / 109.14 ms │     no change │
│ QQuery 32 │        20.02 / 20.14 ±0.16 / 20.45 ms │           19.43 / 19.87 ±0.50 / 20.78 ms │     no change │
│ QQuery 33 │        35.91 / 36.70 ±0.47 / 37.18 ms │           36.15 / 36.68 ±0.39 / 37.15 ms │     no change │
│ QQuery 34 │          9.69 / 9.94 ±0.21 / 10.32 ms │            9.76 / 10.02 ±0.19 / 10.23 ms │     no change │
│ QQuery 35 │        70.62 / 72.70 ±2.08 / 76.37 ms │           70.50 / 72.80 ±2.31 / 76.99 ms │     no change │
│ QQuery 36 │           5.51 / 5.67 ±0.28 / 6.22 ms │              5.43 / 5.57 ±0.24 / 6.05 ms │     no change │
│ QQuery 37 │           6.57 / 6.72 ±0.10 / 6.88 ms │              6.52 / 6.61 ±0.06 / 6.67 ms │     no change │
│ QQuery 38 │        60.02 / 60.64 ±0.75 / 62.10 ms │           59.40 / 59.95 ±0.45 / 60.65 ms │     no change │
│ QQuery 39 │        71.53 / 73.96 ±3.90 / 81.70 ms │           71.64 / 73.02 ±1.54 / 76.04 ms │     no change │
│ QQuery 40 │        23.38 / 24.36 ±0.62 / 25.12 ms │           22.17 / 23.58 ±1.07 / 24.68 ms │     no change │
│ QQuery 41 │        10.97 / 11.21 ±0.28 / 11.74 ms │           11.04 / 11.14 ±0.09 / 11.29 ms │     no change │
│ QQuery 42 │        22.91 / 23.54 ±0.51 / 24.47 ms │           22.91 / 23.56 ±0.53 / 24.36 ms │     no change │
│ QQuery 43 │           4.63 / 4.72 ±0.17 / 5.06 ms │              4.69 / 4.83 ±0.21 / 5.25 ms │     no change │
│ QQuery 44 │           8.50 / 8.62 ±0.10 / 8.78 ms │              8.59 / 8.64 ±0.04 / 8.71 ms │     no change │
│ QQuery 45 │        35.60 / 35.91 ±0.27 / 36.32 ms │           35.13 / 35.57 ±0.23 / 35.77 ms │     no change │
│ QQuery 46 │        11.45 / 12.12 ±1.13 / 14.36 ms │           11.43 / 12.68 ±1.66 / 15.95 ms │     no change │
│ QQuery 47 │     214.57 / 219.61 ±4.51 / 227.51 ms │        215.34 / 218.62 ±2.41 / 221.02 ms │     no change │
│ QQuery 48 │        90.01 / 91.07 ±1.56 / 94.14 ms │           89.35 / 91.15 ±2.26 / 95.60 ms │     no change │
│ QQuery 49 │        68.33 / 69.39 ±1.32 / 71.89 ms │           68.31 / 69.26 ±1.05 / 71.22 ms │     no change │
│ QQuery 50 │        58.02 / 58.86 ±0.89 / 60.45 ms │           57.54 / 58.80 ±1.33 / 61.32 ms │     no change │
│ QQuery 51 │        92.75 / 95.52 ±2.45 / 99.76 ms │          91.56 / 95.77 ±6.09 / 107.89 ms │     no change │
│ QQuery 52 │        23.21 / 23.69 ±0.43 / 24.28 ms │           23.49 / 23.88 ±0.34 / 24.49 ms │     no change │
│ QQuery 53 │        28.69 / 28.88 ±0.15 / 29.07 ms │           28.84 / 29.00 ±0.10 / 29.15 ms │     no change │
│ QQuery 54 │        52.63 / 53.24 ±0.56 / 54.23 ms │           52.30 / 53.60 ±1.39 / 56.23 ms │     no change │
│ QQuery 55 │        22.69 / 22.99 ±0.19 / 23.26 ms │           22.85 / 23.14 ±0.29 / 23.55 ms │     no change │
│ QQuery 56 │        36.60 / 37.36 ±0.43 / 37.91 ms │           37.39 / 39.23 ±2.19 / 43.41 ms │     no change │
│ QQuery 57 │     165.20 / 166.11 ±0.81 / 167.52 ms │        164.97 / 166.52 ±1.65 / 169.49 ms │     no change │
│ QQuery 58 │     106.04 / 107.96 ±2.61 / 112.99 ms │        105.01 / 107.60 ±2.45 / 111.84 ms │     no change │
│ QQuery 59 │     114.61 / 115.43 ±0.64 / 116.45 ms │        113.98 / 115.16 ±1.42 / 117.94 ms │     no change │
│ QQuery 60 │        37.64 / 38.27 ±0.81 / 39.86 ms │           37.96 / 38.52 ±0.41 / 39.23 ms │     no change │
│ QQuery 61 │        10.79 / 10.94 ±0.23 / 11.39 ms │           10.84 / 10.96 ±0.16 / 11.27 ms │     no change │
│ QQuery 62 │        42.55 / 42.88 ±0.20 / 43.08 ms │           42.82 / 43.35 ±0.41 / 43.82 ms │     no change │
│ QQuery 63 │        28.77 / 29.47 ±0.97 / 31.38 ms │           28.52 / 30.05 ±1.69 / 33.27 ms │     no change │
│ QQuery 64 │     356.97 / 359.47 ±1.79 / 361.47 ms │        359.36 / 362.27 ±4.01 / 370.21 ms │     no change │
│ QQuery 65 │     126.65 / 130.47 ±4.64 / 139.13 ms │        130.29 / 132.53 ±2.36 / 135.85 ms │     no change │
│ QQuery 66 │        74.08 / 74.74 ±0.45 / 75.20 ms │           74.02 / 74.63 ±0.52 / 75.46 ms │     no change │
│ QQuery 67 │     241.97 / 247.66 ±5.87 / 258.83 ms │        244.49 / 247.19 ±2.95 / 250.89 ms │     no change │
│ QQuery 68 │        11.64 / 11.83 ±0.16 / 12.13 ms │           11.58 / 11.81 ±0.19 / 12.14 ms │     no change │
│ QQuery 69 │        56.34 / 58.39 ±2.05 / 61.81 ms │           55.62 / 56.24 ±0.44 / 56.82 ms │     no change │
│ QQuery 70 │     102.86 / 104.05 ±0.80 / 104.89 ms │        102.13 / 106.12 ±5.47 / 116.84 ms │     no change │
│ QQuery 71 │        34.36 / 34.97 ±0.53 / 35.82 ms │           34.06 / 34.95 ±0.87 / 36.45 ms │     no change │
│ QQuery 72 │ 1561.27 / 1609.86 ±39.36 / 1666.54 ms │    1516.53 / 1654.61 ±69.41 / 1698.50 ms │     no change │
│ QQuery 73 │          9.63 / 9.90 ±0.35 / 10.58 ms │            9.60 / 10.20 ±0.39 / 10.69 ms │     no change │
│ QQuery 74 │     154.31 / 155.01 ±0.88 / 156.73 ms │        150.74 / 155.23 ±3.87 / 162.21 ms │     no change │
│ QQuery 75 │     138.10 / 140.89 ±2.66 / 145.94 ms │        139.11 / 141.09 ±3.07 / 147.15 ms │     no change │
│ QQuery 76 │        33.01 / 33.44 ±0.39 / 34.11 ms │           34.15 / 35.61 ±2.04 / 39.59 ms │  1.06x slower │
│ QQuery 77 │        59.29 / 60.08 ±0.82 / 61.56 ms │           59.03 / 59.30 ±0.33 / 59.91 ms │     no change │
│ QQuery 78 │     158.53 / 161.03 ±2.33 / 165.37 ms │        157.71 / 163.53 ±6.19 / 175.49 ms │     no change │
│ QQuery 79 │        65.74 / 66.55 ±0.62 / 67.63 ms │           65.46 / 67.98 ±4.35 / 76.67 ms │     no change │
│ QQuery 80 │        93.20 / 95.03 ±2.23 / 99.30 ms │          93.85 / 96.27 ±2.81 / 101.72 ms │     no change │
│ QQuery 81 │        25.50 / 25.69 ±0.17 / 25.90 ms │           25.44 / 25.66 ±0.30 / 26.21 ms │     no change │
│ QQuery 82 │        16.23 / 16.50 ±0.18 / 16.69 ms │           16.15 / 16.41 ±0.27 / 16.93 ms │     no change │
│ QQuery 83 │        32.69 / 33.35 ±1.06 / 35.46 ms │           32.19 / 32.59 ±0.27 / 33.04 ms │     no change │
│ QQuery 84 │        29.18 / 29.73 ±0.51 / 30.61 ms │           29.26 / 31.05 ±2.12 / 35.05 ms │     no change │
│ QQuery 85 │       97.46 / 99.94 ±2.39 / 104.27 ms │          97.39 / 99.88 ±2.00 / 102.10 ms │     no change │
│ QQuery 86 │        24.72 / 24.94 ±0.18 / 25.15 ms │           24.81 / 25.32 ±0.32 / 25.75 ms │     no change │
│ QQuery 87 │        59.74 / 60.27 ±0.33 / 60.62 ms │           59.54 / 60.22 ±0.66 / 61.25 ms │     no change │
│ QQuery 88 │        59.18 / 60.22 ±1.03 / 62.13 ms │           58.74 / 60.76 ±2.70 / 66.09 ms │     no change │
│ QQuery 89 │        34.50 / 35.14 ±0.43 / 35.62 ms │           34.39 / 35.25 ±1.05 / 37.29 ms │     no change │
│ QQuery 90 │        16.12 / 16.33 ±0.19 / 16.70 ms │           15.94 / 16.18 ±0.27 / 16.70 ms │     no change │
│ QQuery 91 │        40.03 / 40.55 ±0.47 / 41.40 ms │           40.47 / 40.72 ±0.14 / 40.85 ms │     no change │
│ QQuery 92 │        28.54 / 29.80 ±1.37 / 32.33 ms │           29.21 / 29.79 ±0.35 / 30.15 ms │     no change │
│ QQuery 93 │        48.37 / 49.60 ±1.42 / 52.30 ms │           48.81 / 50.73 ±2.10 / 54.81 ms │     no change │
│ QQuery 94 │        37.39 / 38.46 ±0.76 / 39.39 ms │           36.85 / 37.37 ±0.50 / 38.25 ms │     no change │
│ QQuery 95 │        78.35 / 79.47 ±0.63 / 80.10 ms │           78.76 / 80.48 ±1.70 / 83.22 ms │     no change │
│ QQuery 96 │        23.04 / 23.34 ±0.29 / 23.87 ms │           23.29 / 23.62 ±0.33 / 24.18 ms │     no change │
│ QQuery 97 │        49.44 / 50.89 ±1.22 / 53.13 ms │           51.90 / 53.35 ±1.52 / 56.20 ms │     no change │
│ QQuery 98 │        41.95 / 42.75 ±0.71 / 43.76 ms │           41.46 / 42.26 ±0.64 / 43.17 ms │     no change │
│ QQuery 99 │        63.69 / 64.16 ±0.40 / 64.81 ms │           63.86 / 64.81 ±0.99 / 66.67 ms │     no change │
└───────────┴───────────────────────────────────────┴──────────────────────────────────────────┴───────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━┓
┃ Benchmark Summary                                       ┃           ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━┩
│ Total Time (HEAD)                                       │ 8803.90ms │
│ Total Time (fix_single-distinct-groupby-memory-usage)   │ 8865.30ms │
│ Average Time (HEAD)                                     │   88.93ms │
│ Average Time (fix_single-distinct-groupby-memory-usage) │   89.55ms │
│ Queries Faster                                          │         1 │
│ Queries Slower                                          │         2 │
│ Queries with No Change                                  │        96 │
│ Queries with Failure                                    │         0 │
└─────────────────────────────────────────────────────────┴───────────┘

Resource Usage

tpcds — base (merge-base)

Metric Value
Wall time 45.0s
Peak memory 2.2 GiB
Avg memory 1.5 GiB
CPU user 190.5s
CPU sys 5.2s
Peak spill 0 B

tpcds — branch

Metric Value
Wall time 45.0s
Peak memory 2.1 GiB
Avg memory 1.4 GiB
CPU user 187.3s
CPU sys 5.4s
Peak spill 0 B

File an issue against this benchmark runner

@adriangbot

Copy link
Copy Markdown

🤖 Benchmark completed (GKE) | trigger

Instance: c4a-highmem-16 (12 vCPU / 65 GiB)

Comparing fix/single-distinct-groupby-memory-usage (0923424) to 334f293 (merge-base) diff

Run configuration
run benchmark clickbench_partitioned
CPU Details (lscpu)
Architecture:                            aarch64
CPU op-mode(s):                          64-bit
Byte Order:                              Little Endian
CPU(s):                                  16
On-line CPU(s) list:                     0-15
Vendor ID:                               ARM
Model name:                              Neoverse-V2
Model:                                   1
Thread(s) per core:                      1
Core(s) per cluster:                     16
Socket(s):                               -
Cluster(s):                              1
Stepping:                                r0p1
BogoMIPS:                                2000.00
Flags:                                   fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 sm3 sm4 asimddp sha512 sve asimdfhm dit uscat ilrcpc flagm sb paca pacg dcpodp sve2 sveaes svepmull svebitperm svesha3 svesm4 flagm2 frint svei8mm svebf16 i8mm bf16 dgh rng bti
L1d cache:                               1 MiB (16 instances)
L1i cache:                               1 MiB (16 instances)
L2 cache:                                32 MiB (16 instances)
L3 cache:                                80 MiB (1 instance)
NUMA node(s):                            1
NUMA node0 CPU(s):                       0-15
Vulnerability Gather data sampling:      Not affected
Vulnerability Indirect target selection: Not affected
Vulnerability Itlb multihit:             Not affected
Vulnerability L1tf:                      Not affected
Vulnerability Mds:                       Not affected
Vulnerability Meltdown:                  Not affected
Vulnerability Mmio stale data:           Not affected
Vulnerability Reg file data sampling:    Not affected
Vulnerability Retbleed:                  Not affected
Vulnerability Spec rstack overflow:      Not affected
Vulnerability Spec store bypass:         Mitigation; Speculative Store Bypass disabled via prctl
Vulnerability Spectre v1:                Mitigation; __user pointer sanitization
Vulnerability Spectre v2:                Mitigation; CSV2, BHB
Vulnerability Srbds:                     Not affected
Vulnerability Tsa:                       Not affected
Vulnerability Tsx async abort:           Not affected
Vulnerability Vmscape:                   Not affected
Details

Comparing HEAD and fix_single-distinct-groupby-memory-usage
--------------------
Benchmark clickbench_partitioned.json
--------------------
┏━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┓
┃ Query     ┃       HEAD ┃ fix_single-distinct-groupby-memory-usage ┃       Change ┃
┡━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━┩
│ QQuery 0  │    1.21 ms │                                  1.24 ms │    no change │
│ QQuery 1  │   11.53 ms │                                 11.81 ms │    no change │
│ QQuery 2  │   36.03 ms │                                 36.11 ms │    no change │
│ QQuery 3  │   32.65 ms │                                 31.71 ms │    no change │
│ QQuery 4  │  242.63 ms │                                632.82 ms │ 2.61x slower │
│ QQuery 5  │  287.61 ms │                                277.62 ms │    no change │
│ QQuery 6  │    1.29 ms │                                  1.23 ms │    no change │
│ QQuery 7  │   13.36 ms │                                 12.91 ms │    no change │
│ QQuery 8  │  349.51 ms │                                376.25 ms │ 1.08x slower │
│ QQuery 9  │  475.90 ms │                                481.50 ms │    no change │
│ QQuery 10 │   65.62 ms │                                 96.97 ms │ 1.48x slower │
│ QQuery 11 │   76.46 ms │                                102.84 ms │ 1.34x slower │
│ QQuery 12 │  272.83 ms │                                266.34 ms │    no change │
│ QQuery 13 │  380.95 ms │                                392.40 ms │    no change │
│ QQuery 14 │  294.61 ms │                                285.95 ms │    no change │
│ QQuery 15 │  294.13 ms │                                300.89 ms │    no change │
│ QQuery 16 │  632.64 ms │                                625.71 ms │    no change │
│ QQuery 17 │  653.41 ms │                                639.50 ms │    no change │
│ QQuery 18 │ 1309.92 ms │                               1333.86 ms │    no change │
│ QQuery 19 │   29.19 ms │                                 27.93 ms │    no change │
│ QQuery 20 │  532.89 ms │                                527.14 ms │    no change │
│ QQuery 21 │  535.80 ms │                                528.26 ms │    no change │
│ QQuery 22 │ 1025.70 ms │                               1020.79 ms │    no change │
│ QQuery 23 │ 3176.32 ms │                               3262.30 ms │    no change │
│ QQuery 24 │   42.25 ms │                                 44.83 ms │ 1.06x slower │
│ QQuery 25 │  108.71 ms │                                107.64 ms │    no change │
│ QQuery 26 │   42.42 ms │                                 42.10 ms │    no change │
│ QQuery 27 │  528.52 ms │                                523.45 ms │    no change │
│ QQuery 28 │ 2938.42 ms │                               2931.53 ms │    no change │
│ QQuery 29 │   39.47 ms │                                 39.54 ms │    no change │
│ QQuery 30 │  323.15 ms │                                318.40 ms │    no change │
│ QQuery 31 │  289.84 ms │                                299.37 ms │    no change │
│ QQuery 32 │ 1165.77 ms │                               1156.05 ms │    no change │
│ QQuery 33 │ 1643.33 ms │                               1644.54 ms │    no change │
│ QQuery 34 │ 1599.86 ms │                               1732.76 ms │ 1.08x slower │
│ QQuery 35 │  311.22 ms │                                308.49 ms │    no change │
│ QQuery 36 │   67.88 ms │                                 66.64 ms │    no change │
│ QQuery 37 │   35.94 ms │                                 35.54 ms │    no change │
│ QQuery 38 │   40.92 ms │                                 44.41 ms │ 1.09x slower │
│ QQuery 39 │  142.77 ms │                                148.70 ms │    no change │
│ QQuery 40 │   14.09 ms │                                 14.70 ms │    no change │
│ QQuery 41 │   13.81 ms │                                 14.57 ms │ 1.06x slower │
│ QQuery 42 │   13.79 ms │                                 13.79 ms │    no change │
└───────────┴────────────┴──────────────────────────────────────────┴──────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┓
┃ Benchmark Summary                                       ┃            ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━┩
│ Total Time (HEAD)                                       │ 20094.34ms │
│ Total Time (fix_single-distinct-groupby-memory-usage)   │ 20761.13ms │
│ Average Time (HEAD)                                     │   467.31ms │
│ Average Time (fix_single-distinct-groupby-memory-usage) │   482.82ms │
│ Queries Faster                                          │          0 │
│ Queries Slower                                          │          8 │
│ Queries with No Change                                  │         35 │
│ Queries with Failure                                    │          0 │
└─────────────────────────────────────────────────────────┴────────────┘

Distribution per query (min / mean ±stddev / max):

Comparing HEAD and fix_single-distinct-groupby-memory-usage
--------------------
Benchmark clickbench_partitioned.json
--------------------
┏━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Query     ┃                                   HEAD ┃ fix_single-distinct-groupby-memory-usage ┃        Change ┃
┡━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ QQuery 0  │           1.21 / 4.43 ±6.29 / 17.01 ms │             1.24 / 4.58 ±6.47 / 17.51 ms │     no change │
│ QQuery 1  │         11.53 / 11.89 ±0.19 / 12.10 ms │           11.81 / 12.12 ±0.16 / 12.26 ms │     no change │
│ QQuery 2  │         36.03 / 36.38 ±0.28 / 36.82 ms │           36.11 / 36.38 ±0.26 / 36.85 ms │     no change │
│ QQuery 3  │         32.65 / 33.14 ±0.59 / 34.04 ms │           31.71 / 32.12 ±0.48 / 33.02 ms │     no change │
│ QQuery 4  │      242.63 / 248.76 ±4.65 / 254.88 ms │        632.82 / 640.21 ±6.94 / 653.00 ms │  2.57x slower │
│ QQuery 5  │      287.61 / 290.33 ±1.85 / 293.06 ms │        277.62 / 281.84 ±2.32 / 284.76 ms │     no change │
│ QQuery 6  │            1.29 / 1.44 ±0.23 / 1.89 ms │              1.23 / 1.40 ±0.26 / 1.90 ms │     no change │
│ QQuery 7  │         13.36 / 13.65 ±0.22 / 13.94 ms │           12.91 / 13.16 ±0.14 / 13.35 ms │     no change │
│ QQuery 8  │      349.51 / 355.51 ±3.20 / 358.77 ms │       376.25 / 402.63 ±13.83 / 416.80 ms │  1.13x slower │
│ QQuery 9  │      475.90 / 482.99 ±5.10 / 490.11 ms │       481.50 / 500.32 ±15.59 / 522.19 ms │     no change │
│ QQuery 10 │         65.62 / 66.63 ±1.00 / 68.16 ms │         96.97 / 106.35 ±5.24 / 110.67 ms │  1.60x slower │
│ QQuery 11 │         76.46 / 76.75 ±0.23 / 77.09 ms │        102.84 / 106.76 ±2.42 / 110.23 ms │  1.39x slower │
│ QQuery 12 │      272.83 / 280.35 ±5.87 / 290.56 ms │       266.34 / 279.84 ±15.02 / 308.77 ms │     no change │
│ QQuery 13 │     380.95 / 397.57 ±19.27 / 433.55 ms │        392.40 / 402.56 ±9.28 / 416.14 ms │     no change │
│ QQuery 14 │      294.61 / 301.79 ±7.45 / 311.21 ms │        285.95 / 296.12 ±8.23 / 308.16 ms │     no change │
│ QQuery 15 │      294.13 / 305.86 ±9.51 / 322.73 ms │       300.89 / 314.38 ±14.12 / 341.32 ms │     no change │
│ QQuery 16 │     632.64 / 651.45 ±16.62 / 679.17 ms │        625.71 / 639.86 ±7.29 / 645.09 ms │     no change │
│ QQuery 17 │     653.41 / 667.01 ±10.17 / 680.65 ms │       639.50 / 666.96 ±16.17 / 686.63 ms │     no change │
│ QQuery 18 │  1309.92 / 1340.50 ±21.83 / 1374.01 ms │    1333.86 / 1347.92 ±14.13 / 1368.19 ms │     no change │
│ QQuery 19 │         29.19 / 36.96 ±9.98 / 54.17 ms │           27.93 / 29.85 ±3.32 / 36.46 ms │ +1.24x faster │
│ QQuery 20 │     532.89 / 542.48 ±10.77 / 563.55 ms │       527.14 / 538.96 ±12.15 / 561.71 ms │     no change │
│ QQuery 21 │      535.80 / 539.31 ±3.49 / 545.50 ms │        528.26 / 536.10 ±8.35 / 549.51 ms │     no change │
│ QQuery 22 │  1025.70 / 1055.17 ±21.43 / 1082.55 ms │    1020.79 / 1077.26 ±45.78 / 1142.31 ms │     no change │
│ QQuery 23 │ 3176.32 / 3424.21 ±141.60 / 3592.26 ms │    3262.30 / 3330.05 ±63.05 / 3447.61 ms │     no change │
│ QQuery 24 │     42.25 / 186.85 ±141.79 / 358.50 ms │       44.83 / 164.26 ±131.18 / 398.39 ms │ +1.14x faster │
│ QQuery 25 │      108.71 / 110.60 ±1.98 / 113.99 ms │        107.64 / 109.55 ±1.38 / 110.85 ms │     no change │
│ QQuery 26 │         42.42 / 43.49 ±0.84 / 44.67 ms │           42.10 / 43.28 ±0.97 / 44.64 ms │     no change │
│ QQuery 27 │      528.52 / 536.13 ±7.33 / 549.30 ms │        523.45 / 527.87 ±3.95 / 533.59 ms │     no change │
│ QQuery 28 │  2938.42 / 2980.13 ±33.70 / 3036.62 ms │    2931.53 / 2976.17 ±25.72 / 2999.24 ms │     no change │
│ QQuery 29 │        39.47 / 53.11 ±16.19 / 75.46 ms │           39.54 / 40.01 ±0.32 / 40.42 ms │ +1.33x faster │
│ QQuery 30 │      323.15 / 332.83 ±8.61 / 346.93 ms │        318.40 / 327.50 ±5.39 / 334.77 ms │     no change │
│ QQuery 31 │      289.84 / 296.37 ±4.24 / 301.76 ms │        299.37 / 300.87 ±1.99 / 304.76 ms │     no change │
│ QQuery 32 │  1165.77 / 1240.12 ±68.48 / 1356.63 ms │    1156.05 / 1231.14 ±67.76 / 1341.70 ms │     no change │
│ QQuery 33 │  1643.33 / 1669.20 ±19.52 / 1689.05 ms │    1644.54 / 1701.23 ±55.20 / 1783.59 ms │     no change │
│ QQuery 34 │  1599.86 / 1685.77 ±46.07 / 1720.38 ms │    1732.76 / 1790.47 ±61.66 / 1897.45 ms │  1.06x slower │
│ QQuery 35 │    311.22 / 396.36 ±141.72 / 678.99 ms │      308.49 / 458.84 ±268.06 / 994.42 ms │  1.16x slower │
│ QQuery 36 │         67.88 / 73.03 ±6.84 / 86.30 ms │           66.64 / 72.60 ±4.78 / 81.05 ms │     no change │
│ QQuery 37 │         35.94 / 36.72 ±0.60 / 37.69 ms │           35.54 / 41.81 ±9.56 / 60.47 ms │  1.14x slower │
│ QQuery 38 │        40.92 / 55.00 ±20.38 / 95.36 ms │          44.41 / 55.05 ±10.54 / 73.37 ms │     no change │
│ QQuery 39 │      142.77 / 154.62 ±7.58 / 166.27 ms │        148.70 / 155.60 ±4.28 / 161.45 ms │     no change │
│ QQuery 40 │         14.09 / 14.62 ±0.41 / 15.36 ms │           14.70 / 16.96 ±3.76 / 24.46 ms │  1.16x slower │
│ QQuery 41 │         13.81 / 18.06 ±8.21 / 34.47 ms │           14.57 / 19.11 ±6.80 / 32.39 ms │  1.06x slower │
│ QQuery 42 │         13.79 / 21.24 ±6.35 / 28.43 ms │           13.79 / 14.04 ±0.21 / 14.33 ms │ +1.51x faster │
└───────────┴────────────────────────────────────────┴──────────────────────────────────────────┴───────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┓
┃ Benchmark Summary                                       ┃            ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━┩
│ Total Time (HEAD)                                       │ 21068.81ms │
│ Total Time (fix_single-distinct-groupby-memory-usage)   │ 21644.10ms │
│ Average Time (HEAD)                                     │   489.97ms │
│ Average Time (fix_single-distinct-groupby-memory-usage) │   503.35ms │
│ Queries Faster                                          │          4 │
│ Queries Slower                                          │          9 │
│ Queries with No Change                                  │         30 │
│ Queries with Failure                                    │          0 │
└─────────────────────────────────────────────────────────┴────────────┘

Resource Usage

clickbench_partitioned — base (merge-base)

Metric Value
Wall time 110.0s
Peak memory 18.6 GiB
Avg memory 5.9 GiB
CPU user 1030.1s
CPU sys 108.4s
Peak spill 0 B

clickbench_partitioned — branch

Metric Value
Wall time 110.0s
Peak memory 17.7 GiB
Avg memory 6.2 GiB
CPU user 1025.3s
CPU sys 110.6s
Peak spill 0 B

File an issue against this benchmark runner

@mkleen

mkleen commented Oct 12, 2026

Copy link
Copy Markdown
Contributor

@mohitgurav20 There are serious performance regressions in the clickhouse benchmark. See #26000 (comment) for more details.

@mohitgurav20

Copy link
Copy Markdown
Contributor Author

Thanks for running the benchmark and flagging this @mkleen.

I analyzed the benchmark run in detail:
Every single regressed query (Q4, Q8, Q10, Q11, Q34, Q35, Q37, Q40, Q41) is a COUNT(DISTINCT "UserID") query where "UserID" is Int64.

Because count.groups_accumulator_supported_for_types(&[Int64], true) returns Some(true), the unconditional rewrite_pays check prevented SingleDistinctToGroupBy from firing on lone distinct queries like SELECT COUNT(DISTINCT UserID) FROM hits.

Without the two-phase rewrite to GROUP BY, the engine cannot leverage RepartitionExec: partitioning=Hash(...) to parallelize deduplication across partitions, and falls back to evaluating distincts serially through the accumulator. That explains the 2.57x regression on Q4 (248 ms -> 640 ms) and the slowdowns on Q10 and Q11.

This confirms that the two-phase rewrite is a critical parallelization optimization for lone distinct queries, even when a specialized GroupsAccumulator exists.

To address this cleanly:
Lone distinct queries (where all aggregates in the plan are DISTINCT on the same expression, with no companion non-distinct aggregates) should always be rewritten to preserve parallel hash aggregation. The heuristic gating should only apply when non-distinct companion aggregates (like count(*) or sum(y)) are present.

Does that direction sound good to you? If so, I'll update the rule accordingly so we preserve ClickBench performance.

…pache#25932)

SingleDistinctToGroupBy converts single DISTINCT aggregate expressions into
a two-phase GROUP BY plan. This enables parallel deduplication via
RepartitionExec hash partitioning, which is critical for lone-distinct
queries like COUNT(DISTINCT x).

However, when companion non-distinct aggregates are present alongside the
distinct aggregate (e.g. SELECT sum(y), count(DISTINCT x)), the companion
aggregates move to the inner group-by at a finer grain. When the distinct
aggregate already has native GroupsAccumulator support, this inner grouping
adds unnecessary memory and CPU overhead without benefiting from adapter
offloading.

This change:
1. Gates SingleDistinctToGroupBy with rewrite_pays() only when companion
   non-distinct aggregates are present.
2. Preserves the two-phase rewrite for pure lone-distinct queries so ClickBench
   and similar workloads maintain parallel deduplication without regression.
3. Consistently handles distinct aggregates with unsupported distinct handling.
4. Updates optimizer plan snapshots and sqllogictests.
@mohitgurav20
mohitgurav20 force-pushed the fix/single-distinct-groupby-memory-usage branch from 287b932 to ac76b0d Compare October 17, 2026 07:46
@mohitgurav20

Copy link
Copy Markdown
Contributor Author

Hi @mkleen, just following up on this when you get a chance.

I've rebased cleanly onto latest main and addressed the ClickBench regression — lone-distinct queries now always retain the 2-phase GROUP BY fanout, while the cost guard only applies when companion aggregates are present. CI and coverage checks are all passing.

Could you trigger a benchmark run whenever convenient? Thanks!

@mkleen

mkleen commented Oct 17, 2026

Copy link
Copy Markdown
Contributor

run benchmarks

@adriangbot

Copy link
Copy Markdown

Benchmark for this request failed before finishing (Kubernetes reason: BackoffLimitExceeded).

Benchmarks requested: clickbench_partitioned

Kubernetes message
Job has reached the specified backoff limit

File an issue against this benchmark runner

@adriangbot

Copy link
Copy Markdown

🤖 Benchmark running (GKE) | trigger
Instance: c4a-highmem-16 (12 vCPU / 65 GiB) | Linux bench-c6235987877-3544-tdnvp 6.12.94+ #1 SMP Fri Aug 21 08:00:16 UTC 2026 aarch64 GNU/Linux

CPU Details (lscpu)
Architecture:                            aarch64
CPU op-mode(s):                          64-bit
Byte Order:                              Little Endian
CPU(s):                                  16
On-line CPU(s) list:                     0-15
Vendor ID:                               ARM
Model name:                              Neoverse-V2
Model:                                   1
Thread(s) per core:                      1
Core(s) per cluster:                     16
Socket(s):                               -
Cluster(s):                              1
Stepping:                                r0p1
BogoMIPS:                                2000.00
Flags:                                   fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 sm3 sm4 asimddp sha512 sve asimdfhm dit uscat ilrcpc flagm sb paca pacg dcpodp sve2 sveaes svepmull svebitperm svesha3 svesm4 flagm2 frint svei8mm svebf16 i8mm bf16 dgh rng bti
L1d cache:                               1 MiB (16 instances)
L1i cache:                               1 MiB (16 instances)
L2 cache:                                32 MiB (16 instances)
L3 cache:                                80 MiB (1 instance)
NUMA node(s):                            1
NUMA node0 CPU(s):                       0-15
Vulnerability Gather data sampling:      Not affected
Vulnerability Indirect target selection: Not affected
Vulnerability Itlb multihit:             Not affected
Vulnerability L1tf:                      Not affected
Vulnerability Mds:                       Not affected
Vulnerability Meltdown:                  Not affected
Vulnerability Mmio stale data:           Not affected
Vulnerability Reg file data sampling:    Not affected
Vulnerability Retbleed:                  Not affected
Vulnerability Spec rstack overflow:      Not affected
Vulnerability Spec store bypass:         Mitigation; Speculative Store Bypass disabled via prctl
Vulnerability Spectre v1:                Mitigation; __user pointer sanitization
Vulnerability Spectre v2:                Mitigation; CSV2, BHB
Vulnerability Srbds:                     Not affected
Vulnerability Tsa:                       Not affected
Vulnerability Tsx async abort:           Not affected
Vulnerability Vmscape:                   Not affected

Comparing fix/single-distinct-groupby-memory-usage (bbf4ccb) to 484183d (merge-base) diff

Run configuration
run benchmark tpch

Results will be posted here when complete


File an issue against this benchmark runner

@adriangbot

Copy link
Copy Markdown

🤖 Benchmark running (GKE) | trigger
Instance: c4a-highmem-16 (12 vCPU / 65 GiB) | Linux bench-c6235987877-3543-kmxlp 6.12.94+ #1 SMP Fri Aug 21 08:00:16 UTC 2026 aarch64 GNU/Linux

CPU Details (lscpu)
Architecture:                            aarch64
CPU op-mode(s):                          64-bit
Byte Order:                              Little Endian
CPU(s):                                  16
On-line CPU(s) list:                     0-15
Vendor ID:                               ARM
Model name:                              Neoverse-V2
Model:                                   1
Thread(s) per core:                      1
Core(s) per cluster:                     16
Socket(s):                               -
Cluster(s):                              1
Stepping:                                r0p1
BogoMIPS:                                2000.00
Flags:                                   fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 sm3 sm4 asimddp sha512 sve asimdfhm dit uscat ilrcpc flagm sb paca pacg dcpodp sve2 sveaes svepmull svebitperm svesha3 svesm4 flagm2 frint svei8mm svebf16 i8mm bf16 dgh rng bti
L1d cache:                               1 MiB (16 instances)
L1i cache:                               1 MiB (16 instances)
L2 cache:                                32 MiB (16 instances)
L3 cache:                                80 MiB (1 instance)
NUMA node(s):                            1
NUMA node0 CPU(s):                       0-15
Vulnerability Gather data sampling:      Not affected
Vulnerability Indirect target selection: Not affected
Vulnerability Itlb multihit:             Not affected
Vulnerability L1tf:                      Not affected
Vulnerability Mds:                       Not affected
Vulnerability Meltdown:                  Not affected
Vulnerability Mmio stale data:           Not affected
Vulnerability Reg file data sampling:    Not affected
Vulnerability Retbleed:                  Not affected
Vulnerability Spec rstack overflow:      Not affected
Vulnerability Spec store bypass:         Mitigation; Speculative Store Bypass disabled via prctl
Vulnerability Spectre v1:                Mitigation; __user pointer sanitization
Vulnerability Spectre v2:                Mitigation; CSV2, BHB
Vulnerability Srbds:                     Not affected
Vulnerability Tsa:                       Not affected
Vulnerability Tsx async abort:           Not affected
Vulnerability Vmscape:                   Not affected

Comparing fix/single-distinct-groupby-memory-usage (bbf4ccb) to 484183d (merge-base) diff

Run configuration
run benchmark tpcds

Results will be posted here when complete


File an issue against this benchmark runner

@adriangbot

Copy link
Copy Markdown

🤖 Benchmark completed (GKE) | trigger

Instance: c4a-highmem-16 (12 vCPU / 65 GiB)

Comparing fix/single-distinct-groupby-memory-usage (bbf4ccb) to 484183d (merge-base) diff

Run configuration
run benchmark tpch
CPU Details (lscpu)
Architecture:                            aarch64
CPU op-mode(s):                          64-bit
Byte Order:                              Little Endian
CPU(s):                                  16
On-line CPU(s) list:                     0-15
Vendor ID:                               ARM
Model name:                              Neoverse-V2
Model:                                   1
Thread(s) per core:                      1
Core(s) per cluster:                     16
Socket(s):                               -
Cluster(s):                              1
Stepping:                                r0p1
BogoMIPS:                                2000.00
Flags:                                   fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 sm3 sm4 asimddp sha512 sve asimdfhm dit uscat ilrcpc flagm sb paca pacg dcpodp sve2 sveaes svepmull svebitperm svesha3 svesm4 flagm2 frint svei8mm svebf16 i8mm bf16 dgh rng bti
L1d cache:                               1 MiB (16 instances)
L1i cache:                               1 MiB (16 instances)
L2 cache:                                32 MiB (16 instances)
L3 cache:                                80 MiB (1 instance)
NUMA node(s):                            1
NUMA node0 CPU(s):                       0-15
Vulnerability Gather data sampling:      Not affected
Vulnerability Indirect target selection: Not affected
Vulnerability Itlb multihit:             Not affected
Vulnerability L1tf:                      Not affected
Vulnerability Mds:                       Not affected
Vulnerability Meltdown:                  Not affected
Vulnerability Mmio stale data:           Not affected
Vulnerability Reg file data sampling:    Not affected
Vulnerability Retbleed:                  Not affected
Vulnerability Spec rstack overflow:      Not affected
Vulnerability Spec store bypass:         Mitigation; Speculative Store Bypass disabled via prctl
Vulnerability Spectre v1:                Mitigation; __user pointer sanitization
Vulnerability Spectre v2:                Mitigation; CSV2, BHB
Vulnerability Srbds:                     Not affected
Vulnerability Tsa:                       Not affected
Vulnerability Tsx async abort:           Not affected
Vulnerability Vmscape:                   Not affected
Details

Comparing HEAD and fix_single-distinct-groupby-memory-usage
--------------------
Benchmark tpch_sf1.json
--------------------
┏━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━┓
┃ Query     ┃     HEAD ┃ fix_single-distinct-groupby-memory-usage ┃    Change ┃
┡━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━┩
│ QQuery 1  │ 40.67 ms │                                 40.37 ms │ no change │
│ QQuery 2  │ 18.39 ms │                                 18.09 ms │ no change │
│ QQuery 3  │ 28.50 ms │                                 28.33 ms │ no change │
│ QQuery 4  │ 17.29 ms │                                 17.34 ms │ no change │
│ QQuery 5  │ 35.11 ms │                                 35.10 ms │ no change │
│ QQuery 6  │ 13.51 ms │                                 13.59 ms │ no change │
│ QQuery 7  │ 41.82 ms │                                 42.07 ms │ no change │
│ QQuery 8  │ 40.50 ms │                                 40.89 ms │ no change │
│ QQuery 9  │ 50.27 ms │                                 50.25 ms │ no change │
│ QQuery 10 │ 40.05 ms │                                 39.91 ms │ no change │
│ QQuery 11 │ 13.35 ms │                                 13.22 ms │ no change │
│ QQuery 12 │ 18.08 ms │                                 18.14 ms │ no change │
│ QQuery 13 │ 39.00 ms │                                 38.85 ms │ no change │
│ QQuery 14 │ 24.47 ms │                                 24.35 ms │ no change │
│ QQuery 15 │ 30.59 ms │                                 30.87 ms │ no change │
│ QQuery 16 │ 13.79 ms │                                 13.68 ms │ no change │
│ QQuery 17 │ 73.73 ms │                                 74.40 ms │ no change │
│ QQuery 18 │ 45.89 ms │                                 44.98 ms │ no change │
│ QQuery 19 │ 31.69 ms │                                 31.94 ms │ no change │
│ QQuery 20 │ 31.72 ms │                                 31.52 ms │ no change │
│ QQuery 21 │ 55.44 ms │                                 55.01 ms │ no change │
│ QQuery 22 │ 13.86 ms │                                 13.58 ms │ no change │
└───────────┴──────────┴──────────────────────────────────────────┴───────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┓
┃ Benchmark Summary                                       ┃          ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━┩
│ Total Time (HEAD)                                       │ 717.73ms │
│ Total Time (fix_single-distinct-groupby-memory-usage)   │ 716.49ms │
│ Average Time (HEAD)                                     │  32.62ms │
│ Average Time (fix_single-distinct-groupby-memory-usage) │  32.57ms │
│ Queries Faster                                          │        0 │
│ Queries Slower                                          │        0 │
│ Queries with No Change                                  │       22 │
│ Queries with Failure                                    │        0 │
└─────────────────────────────────────────────────────────┴──────────┘

Distribution per query (min / mean ±stddev / max):

Comparing HEAD and fix_single-distinct-groupby-memory-usage
--------------------
Benchmark tpch_sf1.json
--------------------
┏━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Query     ┃                           HEAD ┃ fix_single-distinct-groupby-memory-usage ┃        Change ┃
┡━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ QQuery 1  │ 40.67 / 42.14 ±1.51 / 44.08 ms │           40.37 / 41.96 ±1.30 / 43.33 ms │     no change │
│ QQuery 2  │ 18.39 / 19.19 ±0.90 / 20.40 ms │           18.09 / 18.49 ±0.34 / 19.07 ms │     no change │
│ QQuery 3  │ 28.50 / 28.76 ±0.18 / 28.92 ms │           28.33 / 28.65 ±0.32 / 29.17 ms │     no change │
│ QQuery 4  │ 17.29 / 17.49 ±0.16 / 17.72 ms │           17.34 / 17.66 ±0.45 / 18.56 ms │     no change │
│ QQuery 5  │ 35.11 / 35.42 ±0.16 / 35.60 ms │           35.10 / 35.40 ±0.37 / 36.10 ms │     no change │
│ QQuery 6  │ 13.51 / 13.88 ±0.49 / 14.85 ms │           13.59 / 14.13 ±0.58 / 15.19 ms │     no change │
│ QQuery 7  │ 41.82 / 43.34 ±1.48 / 45.84 ms │           42.07 / 44.04 ±1.45 / 46.47 ms │     no change │
│ QQuery 8  │ 40.50 / 41.22 ±0.78 / 42.72 ms │           40.89 / 42.57 ±1.51 / 44.91 ms │     no change │
│ QQuery 9  │ 50.27 / 54.13 ±5.41 / 64.89 ms │           50.25 / 51.03 ±0.42 / 51.48 ms │ +1.06x faster │
│ QQuery 10 │ 40.05 / 41.52 ±1.68 / 44.76 ms │           39.91 / 40.32 ±0.25 / 40.60 ms │     no change │
│ QQuery 11 │ 13.35 / 13.51 ±0.18 / 13.82 ms │           13.22 / 13.44 ±0.23 / 13.84 ms │     no change │
│ QQuery 12 │ 18.08 / 18.40 ±0.44 / 19.27 ms │           18.14 / 18.36 ±0.21 / 18.65 ms │     no change │
│ QQuery 13 │ 39.00 / 40.81 ±1.87 / 44.16 ms │           38.85 / 39.20 ±0.30 / 39.74 ms │     no change │
│ QQuery 14 │ 24.47 / 24.66 ±0.15 / 24.81 ms │           24.35 / 24.64 ±0.16 / 24.83 ms │     no change │
│ QQuery 15 │ 30.59 / 31.64 ±1.28 / 33.91 ms │           30.87 / 31.52 ±0.80 / 33.08 ms │     no change │
│ QQuery 16 │ 13.79 / 13.91 ±0.12 / 14.11 ms │           13.68 / 13.80 ±0.15 / 14.07 ms │     no change │
│ QQuery 17 │ 73.73 / 77.96 ±2.40 / 80.84 ms │           74.40 / 75.50 ±1.06 / 77.01 ms │     no change │
│ QQuery 18 │ 45.89 / 47.52 ±1.90 / 50.68 ms │           44.98 / 45.83 ±0.58 / 46.78 ms │     no change │
│ QQuery 19 │ 31.69 / 31.89 ±0.16 / 32.11 ms │           31.94 / 33.24 ±1.46 / 35.38 ms │     no change │
│ QQuery 20 │ 31.72 / 32.78 ±1.51 / 35.77 ms │           31.52 / 31.95 ±0.43 / 32.76 ms │     no change │
│ QQuery 21 │ 55.44 / 57.10 ±2.33 / 61.65 ms │           55.01 / 56.23 ±1.22 / 58.38 ms │     no change │
│ QQuery 22 │ 13.86 / 13.95 ±0.07 / 14.04 ms │           13.58 / 13.86 ±0.30 / 14.39 ms │     no change │
└───────────┴────────────────────────────────┴──────────────────────────────────────────┴───────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┓
┃ Benchmark Summary                                       ┃          ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━┩
│ Total Time (HEAD)                                       │ 741.21ms │
│ Total Time (fix_single-distinct-groupby-memory-usage)   │ 731.82ms │
│ Average Time (HEAD)                                     │  33.69ms │
│ Average Time (fix_single-distinct-groupby-memory-usage) │  33.26ms │
│ Queries Faster                                          │        1 │
│ Queries Slower                                          │        0 │
│ Queries with No Change                                  │       21 │
│ Queries with Failure                                    │        0 │
└─────────────────────────────────────────────────────────┴──────────┘

Resource Usage

tpch — base (merge-base)

Metric Value
Wall time 5.0s
Peak memory 1.1 GiB
Avg memory 480.6 MiB
CPU user 20.0s
CPU sys 1.7s
Peak spill 0 B

tpch — branch

Metric Value
Wall time 5.0s
Peak memory 1.1 GiB
Avg memory 489.3 MiB
CPU user 19.9s
CPU sys 1.6s
Peak spill 0 B

File an issue against this benchmark runner

@adriangbot

Copy link
Copy Markdown

🤖 Benchmark completed (GKE) | trigger

Instance: c4a-highmem-16 (12 vCPU / 65 GiB)

Comparing fix/single-distinct-groupby-memory-usage (bbf4ccb) to 484183d (merge-base) diff

Run configuration
run benchmark tpcds
CPU Details (lscpu)
Architecture:                            aarch64
CPU op-mode(s):                          64-bit
Byte Order:                              Little Endian
CPU(s):                                  16
On-line CPU(s) list:                     0-15
Vendor ID:                               ARM
Model name:                              Neoverse-V2
Model:                                   1
Thread(s) per core:                      1
Core(s) per cluster:                     16
Socket(s):                               -
Cluster(s):                              1
Stepping:                                r0p1
BogoMIPS:                                2000.00
Flags:                                   fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 sm3 sm4 asimddp sha512 sve asimdfhm dit uscat ilrcpc flagm sb paca pacg dcpodp sve2 sveaes svepmull svebitperm svesha3 svesm4 flagm2 frint svei8mm svebf16 i8mm bf16 dgh rng bti
L1d cache:                               1 MiB (16 instances)
L1i cache:                               1 MiB (16 instances)
L2 cache:                                32 MiB (16 instances)
L3 cache:                                80 MiB (1 instance)
NUMA node(s):                            1
NUMA node0 CPU(s):                       0-15
Vulnerability Gather data sampling:      Not affected
Vulnerability Indirect target selection: Not affected
Vulnerability Itlb multihit:             Not affected
Vulnerability L1tf:                      Not affected
Vulnerability Mds:                       Not affected
Vulnerability Meltdown:                  Not affected
Vulnerability Mmio stale data:           Not affected
Vulnerability Reg file data sampling:    Not affected
Vulnerability Retbleed:                  Not affected
Vulnerability Spec rstack overflow:      Not affected
Vulnerability Spec store bypass:         Mitigation; Speculative Store Bypass disabled via prctl
Vulnerability Spectre v1:                Mitigation; __user pointer sanitization
Vulnerability Spectre v2:                Mitigation; CSV2, BHB
Vulnerability Srbds:                     Not affected
Vulnerability Tsa:                       Not affected
Vulnerability Tsx async abort:           Not affected
Vulnerability Vmscape:                   Not affected
Details

Comparing HEAD and fix_single-distinct-groupby-memory-usage
--------------------
Benchmark tpcds_sf1.json
--------------------
┏━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Query     ┃       HEAD ┃ fix_single-distinct-groupby-memory-usage ┃        Change ┃
┡━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ QQuery 1  │    5.76 ms │                                  5.61 ms │     no change │
│ QQuery 2  │   83.34 ms │                                 82.53 ms │     no change │
│ QQuery 3  │   29.31 ms │                                 28.98 ms │     no change │
│ QQuery 4  │  502.51 ms │                                500.69 ms │     no change │
│ QQuery 5  │   52.20 ms │                                 50.92 ms │     no change │
│ QQuery 6  │   37.43 ms │                                 37.04 ms │     no change │
│ QQuery 7  │   72.79 ms │                                 73.03 ms │     no change │
│ QQuery 8  │   37.65 ms │                                 36.88 ms │     no change │
│ QQuery 9  │   51.43 ms │                                 52.06 ms │     no change │
│ QQuery 10 │   61.69 ms │                                 61.48 ms │     no change │
│ QQuery 11 │  321.78 ms │                                323.56 ms │     no change │
│ QQuery 12 │   30.62 ms │                                 30.13 ms │     no change │
│ QQuery 13 │  116.96 ms │                                116.41 ms │     no change │
│ QQuery 14 │  397.30 ms │                                390.83 ms │     no change │
│ QQuery 15 │   63.64 ms │                                 62.10 ms │     no change │
│ QQuery 16 │    6.91 ms │                                  5.75 ms │ +1.20x faster │
│ QQuery 17 │   82.26 ms │                                 81.07 ms │     no change │
│ QQuery 18 │  110.93 ms │                                109.86 ms │     no change │
│ QQuery 19 │   42.66 ms │                                 42.21 ms │     no change │
│ QQuery 20 │   38.31 ms │                                 36.82 ms │     no change │
│ QQuery 21 │   17.86 ms │                                 17.91 ms │     no change │
│ QQuery 22 │   71.45 ms │                                 68.67 ms │     no change │
│ QQuery 23 │  334.68 ms │                                324.91 ms │     no change │
│ QQuery 24 │  203.53 ms │                                203.23 ms │     no change │
│ QQuery 25 │  110.79 ms │                                111.25 ms │     no change │
│ QQuery 26 │   47.26 ms │                                 46.94 ms │     no change │
│ QQuery 27 │    6.42 ms │                                  6.28 ms │     no change │
│ QQuery 28 │   62.26 ms │                                 61.00 ms │     no change │
│ QQuery 29 │   97.67 ms │                                 97.65 ms │     no change │
│ QQuery 30 │   35.46 ms │                                 34.68 ms │     no change │
│ QQuery 31 │  112.48 ms │                                111.69 ms │     no change │
│ QQuery 32 │   21.52 ms │                                 21.14 ms │     no change │
│ QQuery 33 │   36.96 ms │                                 37.56 ms │     no change │
│ QQuery 34 │   10.61 ms │                                 10.55 ms │     no change │
│ QQuery 35 │   78.82 ms │                                 76.71 ms │     no change │
│ QQuery 36 │    6.34 ms │                                  6.12 ms │     no change │
│ QQuery 37 │    7.41 ms │                                  7.27 ms │     no change │
│ QQuery 38 │   65.79 ms │                                 64.30 ms │     no change │
│ QQuery 39 │   77.44 ms │                                 77.08 ms │     no change │
│ QQuery 40 │   24.94 ms │                                 25.35 ms │     no change │
│ QQuery 41 │   13.24 ms │                                 13.23 ms │     no change │
│ QQuery 42 │   24.48 ms │                                 24.37 ms │     no change │
│ QQuery 43 │    5.56 ms │                                  5.37 ms │     no change │
│ QQuery 44 │    9.69 ms │                                  9.31 ms │     no change │
│ QQuery 45 │   44.49 ms │                                 42.06 ms │ +1.06x faster │
│ QQuery 46 │   12.61 ms │                                 12.02 ms │     no change │
│ QQuery 47 │  254.85 ms │                                251.01 ms │     no change │
│ QQuery 48 │   92.44 ms │                                 92.45 ms │     no change │
│ QQuery 49 │   70.91 ms │                                 71.63 ms │     no change │
│ QQuery 50 │   59.20 ms │                                 60.64 ms │     no change │
│ QQuery 51 │   94.43 ms │                                 94.21 ms │     no change │
│ QQuery 52 │   24.52 ms │                                 24.45 ms │     no change │
│ QQuery 53 │   29.89 ms │                                 29.63 ms │     no change │
│ QQuery 54 │   54.40 ms │                                 55.36 ms │     no change │
│ QQuery 55 │   24.08 ms │                                 24.53 ms │     no change │
│ QQuery 56 │   38.14 ms │                                 39.34 ms │     no change │
│ QQuery 57 │  175.74 ms │                                176.96 ms │     no change │
│ QQuery 58 │  109.56 ms │                                108.10 ms │     no change │
│ QQuery 59 │  118.72 ms │                                118.25 ms │     no change │
│ QQuery 60 │   39.22 ms │                                 38.47 ms │     no change │
│ QQuery 61 │   11.47 ms │                                 11.06 ms │     no change │
│ QQuery 62 │   45.61 ms │                                 44.62 ms │     no change │
│ QQuery 63 │   30.70 ms │                                 29.84 ms │     no change │
│ QQuery 64 │  382.12 ms │                                378.06 ms │     no change │
│ QQuery 65 │  134.53 ms │                                135.66 ms │     no change │
│ QQuery 66 │   81.57 ms │                                 78.90 ms │     no change │
│ QQuery 67 │  278.86 ms │                                273.26 ms │     no change │
│ QQuery 68 │   12.57 ms │                                 12.19 ms │     no change │
│ QQuery 69 │   58.06 ms │                                 56.32 ms │     no change │
│ QQuery 70 │  105.08 ms │                                108.50 ms │     no change │
│ QQuery 71 │   35.12 ms │                                 35.08 ms │     no change │
│ QQuery 72 │ 1752.61 ms │                               1767.53 ms │     no change │
│ QQuery 73 │   11.08 ms │                                 10.82 ms │     no change │
│ QQuery 74 │  181.96 ms │                                175.91 ms │     no change │
│ QQuery 75 │  145.70 ms │                                142.97 ms │     no change │
│ QQuery 76 │   35.64 ms │                                 35.35 ms │     no change │
│ QQuery 77 │   62.01 ms │                                 60.58 ms │     no change │
│ QQuery 78 │  176.13 ms │                                172.60 ms │     no change │
│ QQuery 79 │   69.51 ms │                                 69.10 ms │     no change │
│ QQuery 80 │   97.89 ms │                                 99.09 ms │     no change │
│ QQuery 81 │   26.94 ms │                                 27.29 ms │     no change │
│ QQuery 82 │   17.74 ms │                                 17.44 ms │     no change │
│ QQuery 83 │   34.33 ms │                                 33.93 ms │     no change │
│ QQuery 84 │   30.52 ms │                                 30.68 ms │     no change │
│ QQuery 85 │  101.40 ms │                                100.67 ms │     no change │
│ QQuery 86 │   26.63 ms │                                 26.44 ms │     no change │
│ QQuery 87 │   65.36 ms │                                 66.12 ms │     no change │
│ QQuery 88 │   60.27 ms │                                 60.34 ms │     no change │
│ QQuery 89 │   35.42 ms │                                 35.78 ms │     no change │
│ QQuery 90 │   16.90 ms │                                 16.79 ms │     no change │
│ QQuery 91 │   42.27 ms │                                 42.22 ms │     no change │
│ QQuery 92 │   30.67 ms │                                 30.82 ms │     no change │
│ QQuery 93 │   52.44 ms │                                 50.99 ms │     no change │
│ QQuery 94 │   39.36 ms │                                 38.83 ms │     no change │
│ QQuery 95 │   81.90 ms │                                 81.02 ms │     no change │
│ QQuery 96 │   24.10 ms │                                 24.19 ms │     no change │
│ QQuery 97 │   52.26 ms │                                 52.34 ms │     no change │
│ QQuery 98 │   45.90 ms │                                 45.76 ms │     no change │
│ QQuery 99 │   67.39 ms │                                 67.10 ms │     no change │
└───────────┴────────────┴──────────────────────────────────────────┴───────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━┓
┃ Benchmark Summary                                       ┃           ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━┩
│ Total Time (HEAD)                                       │ 9431.37ms │
│ Total Time (fix_single-distinct-groupby-memory-usage)   │ 9375.86ms │
│ Average Time (HEAD)                                     │   95.27ms │
│ Average Time (fix_single-distinct-groupby-memory-usage) │   94.71ms │
│ Queries Faster                                          │         2 │
│ Queries Slower                                          │         0 │
│ Queries with No Change                                  │        97 │
│ Queries with Failure                                    │         0 │
└─────────────────────────────────────────────────────────┴───────────┘

Distribution per query (min / mean ±stddev / max):

Comparing HEAD and fix_single-distinct-groupby-memory-usage
--------------------
Benchmark tpcds_sf1.json
--------------------
┏━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Query     ┃                                  HEAD ┃ fix_single-distinct-groupby-memory-usage ┃        Change ┃
┡━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ QQuery 1  │           5.76 / 6.51 ±1.25 / 9.01 ms │              5.61 / 6.28 ±1.02 / 8.31 ms │     no change │
│ QQuery 2  │        83.34 / 84.35 ±1.20 / 86.66 ms │           82.53 / 82.91 ±0.29 / 83.27 ms │     no change │
│ QQuery 3  │        29.31 / 29.46 ±0.14 / 29.63 ms │           28.98 / 29.13 ±0.11 / 29.32 ms │     no change │
│ QQuery 4  │     502.51 / 513.59 ±7.66 / 523.98 ms │        500.69 / 510.80 ±6.18 / 519.55 ms │     no change │
│ QQuery 5  │        52.20 / 52.80 ±0.46 / 53.59 ms │           50.92 / 51.36 ±0.33 / 51.84 ms │     no change │
│ QQuery 6  │        37.43 / 38.04 ±0.41 / 38.66 ms │           37.04 / 37.32 ±0.24 / 37.69 ms │     no change │
│ QQuery 7  │        72.79 / 73.79 ±0.64 / 74.37 ms │           73.03 / 73.81 ±0.48 / 74.52 ms │     no change │
│ QQuery 8  │        37.65 / 38.98 ±2.18 / 43.31 ms │           36.88 / 37.57 ±0.63 / 38.70 ms │     no change │
│ QQuery 9  │        51.43 / 56.48 ±3.88 / 62.96 ms │           52.06 / 53.50 ±1.12 / 54.68 ms │ +1.06x faster │
│ QQuery 10 │        61.69 / 62.23 ±0.49 / 63.15 ms │           61.48 / 61.74 ±0.24 / 62.18 ms │     no change │
│ QQuery 11 │     321.78 / 328.18 ±6.07 / 336.32 ms │        323.56 / 326.71 ±3.21 / 332.68 ms │     no change │
│ QQuery 12 │        30.62 / 31.08 ±0.37 / 31.54 ms │           30.13 / 30.68 ±0.46 / 31.37 ms │     no change │
│ QQuery 13 │     116.96 / 119.23 ±1.29 / 120.95 ms │        116.41 / 117.54 ±0.71 / 118.30 ms │     no change │
│ QQuery 14 │     397.30 / 398.53 ±2.09 / 402.69 ms │        390.83 / 399.46 ±5.41 / 407.34 ms │     no change │
│ QQuery 15 │        63.64 / 65.40 ±2.18 / 69.70 ms │           62.10 / 62.85 ±0.88 / 64.28 ms │     no change │
│ QQuery 16 │           6.91 / 7.05 ±0.16 / 7.33 ms │              5.75 / 5.93 ±0.11 / 6.07 ms │ +1.19x faster │
│ QQuery 17 │        82.26 / 83.66 ±1.49 / 86.32 ms │           81.07 / 82.14 ±1.67 / 85.46 ms │     no change │
│ QQuery 18 │     110.93 / 112.40 ±0.79 / 113.10 ms │        109.86 / 111.17 ±1.25 / 113.36 ms │     no change │
│ QQuery 19 │        42.66 / 42.87 ±0.18 / 43.19 ms │           42.21 / 42.72 ±0.61 / 43.92 ms │     no change │
│ QQuery 20 │        38.31 / 40.11 ±3.04 / 46.16 ms │           36.82 / 38.77 ±1.54 / 41.48 ms │     no change │
│ QQuery 21 │        17.86 / 18.34 ±0.33 / 18.81 ms │           17.91 / 18.06 ±0.17 / 18.40 ms │     no change │
│ QQuery 22 │        71.45 / 72.41 ±1.02 / 73.90 ms │           68.67 / 69.91 ±0.83 / 71.28 ms │     no change │
│ QQuery 23 │     334.68 / 337.16 ±2.62 / 342.04 ms │        324.91 / 335.63 ±6.63 / 342.70 ms │     no change │
│ QQuery 24 │     203.53 / 213.89 ±7.41 / 223.61 ms │        203.23 / 212.19 ±6.51 / 221.49 ms │     no change │
│ QQuery 25 │     110.79 / 113.44 ±2.07 / 117.17 ms │        111.25 / 112.98 ±1.78 / 116.36 ms │     no change │
│ QQuery 26 │        47.26 / 48.84 ±2.14 / 53.03 ms │           46.94 / 49.00 ±2.97 / 54.87 ms │     no change │
│ QQuery 27 │           6.42 / 6.53 ±0.11 / 6.72 ms │              6.28 / 6.43 ±0.10 / 6.54 ms │     no change │
│ QQuery 28 │        62.26 / 63.09 ±0.63 / 64.01 ms │           61.00 / 61.78 ±0.47 / 62.49 ms │     no change │
│ QQuery 29 │       97.67 / 99.13 ±1.36 / 101.19 ms │          97.65 / 99.49 ±1.55 / 101.85 ms │     no change │
│ QQuery 30 │        35.46 / 38.37 ±4.48 / 47.29 ms │           34.68 / 36.58 ±2.98 / 42.51 ms │     no change │
│ QQuery 31 │     112.48 / 113.58 ±0.87 / 114.67 ms │        111.69 / 112.91 ±0.67 / 113.51 ms │     no change │
│ QQuery 32 │        21.52 / 21.74 ±0.20 / 21.99 ms │           21.14 / 21.58 ±0.38 / 22.27 ms │     no change │
│ QQuery 33 │        36.96 / 37.45 ±0.25 / 37.65 ms │           37.56 / 37.86 ±0.32 / 38.34 ms │     no change │
│ QQuery 34 │        10.61 / 12.36 ±3.02 / 18.38 ms │           10.55 / 11.06 ±0.59 / 12.18 ms │ +1.12x faster │
│ QQuery 35 │        78.82 / 79.70 ±0.88 / 81.24 ms │           76.71 / 78.87 ±2.41 / 83.07 ms │     no change │
│ QQuery 36 │           6.34 / 6.48 ±0.14 / 6.72 ms │              6.12 / 6.18 ±0.07 / 6.30 ms │     no change │
│ QQuery 37 │           7.41 / 7.51 ±0.07 / 7.59 ms │              7.27 / 7.45 ±0.16 / 7.69 ms │     no change │
│ QQuery 38 │        65.79 / 67.55 ±1.23 / 69.00 ms │           64.30 / 65.31 ±0.74 / 66.31 ms │     no change │
│ QQuery 39 │        77.44 / 80.02 ±2.65 / 84.87 ms │           77.08 / 78.76 ±1.83 / 81.91 ms │     no change │
│ QQuery 40 │        24.94 / 25.55 ±0.42 / 25.97 ms │           25.35 / 25.68 ±0.33 / 26.17 ms │     no change │
│ QQuery 41 │        13.24 / 13.28 ±0.04 / 13.35 ms │           13.23 / 13.99 ±1.28 / 16.55 ms │  1.05x slower │
│ QQuery 42 │        24.48 / 24.88 ±0.48 / 25.75 ms │           24.37 / 24.84 ±0.54 / 25.83 ms │     no change │
│ QQuery 43 │           5.56 / 5.61 ±0.05 / 5.67 ms │              5.37 / 5.48 ±0.08 / 5.61 ms │     no change │
│ QQuery 44 │          9.69 / 9.91 ±0.17 / 10.11 ms │              9.31 / 9.44 ±0.10 / 9.57 ms │     no change │
│ QQuery 45 │        44.49 / 45.52 ±0.85 / 46.83 ms │           42.06 / 43.48 ±1.33 / 45.96 ms │     no change │
│ QQuery 46 │        12.61 / 12.77 ±0.17 / 13.02 ms │           12.02 / 12.48 ±0.30 / 12.84 ms │     no change │
│ QQuery 47 │     254.85 / 261.77 ±5.99 / 272.95 ms │        251.01 / 253.36 ±2.68 / 258.51 ms │     no change │
│ QQuery 48 │        92.44 / 92.64 ±0.18 / 92.90 ms │           92.45 / 93.91 ±1.22 / 95.57 ms │     no change │
│ QQuery 49 │        70.91 / 72.53 ±1.13 / 74.12 ms │           71.63 / 72.60 ±0.84 / 73.69 ms │     no change │
│ QQuery 50 │        59.20 / 60.51 ±0.85 / 61.88 ms │           60.64 / 62.96 ±3.99 / 70.89 ms │     no change │
│ QQuery 51 │        94.43 / 95.66 ±0.78 / 96.84 ms │          94.21 / 96.98 ±3.05 / 102.89 ms │     no change │
│ QQuery 52 │        24.52 / 25.26 ±0.96 / 27.17 ms │           24.45 / 24.83 ±0.27 / 25.07 ms │     no change │
│ QQuery 53 │        29.89 / 31.93 ±2.97 / 37.79 ms │           29.63 / 29.85 ±0.15 / 30.05 ms │ +1.07x faster │
│ QQuery 54 │        54.40 / 54.77 ±0.45 / 55.63 ms │           55.36 / 57.78 ±4.11 / 65.99 ms │  1.05x slower │
│ QQuery 55 │        24.08 / 24.45 ±0.39 / 25.04 ms │           24.53 / 24.78 ±0.30 / 25.36 ms │     no change │
│ QQuery 56 │        38.14 / 38.58 ±0.37 / 39.07 ms │           39.34 / 39.89 ±0.46 / 40.50 ms │     no change │
│ QQuery 57 │     175.74 / 178.61 ±2.61 / 183.20 ms │        176.96 / 179.00 ±2.06 / 182.96 ms │     no change │
│ QQuery 58 │     109.56 / 111.33 ±1.96 / 114.88 ms │        108.10 / 109.77 ±1.15 / 111.53 ms │     no change │
│ QQuery 59 │     118.72 / 119.92 ±0.65 / 120.71 ms │        118.25 / 120.25 ±1.84 / 123.46 ms │     no change │
│ QQuery 60 │        39.22 / 39.58 ±0.29 / 40.05 ms │           38.47 / 39.33 ±0.65 / 40.36 ms │     no change │
│ QQuery 61 │        11.47 / 11.63 ±0.13 / 11.76 ms │           11.06 / 11.31 ±0.15 / 11.49 ms │     no change │
│ QQuery 62 │        45.61 / 47.46 ±2.02 / 51.10 ms │           44.62 / 46.42 ±2.58 / 51.53 ms │     no change │
│ QQuery 63 │        30.70 / 30.91 ±0.13 / 31.10 ms │           29.84 / 30.50 ±0.42 / 30.99 ms │     no change │
│ QQuery 64 │     382.12 / 384.93 ±1.96 / 388.02 ms │        378.06 / 383.83 ±6.81 / 396.52 ms │     no change │
│ QQuery 65 │     134.53 / 137.91 ±1.99 / 140.28 ms │        135.66 / 138.42 ±2.31 / 142.12 ms │     no change │
│ QQuery 66 │        81.57 / 83.02 ±1.82 / 86.34 ms │           78.90 / 81.26 ±4.02 / 89.27 ms │     no change │
│ QQuery 67 │     278.86 / 283.02 ±2.90 / 287.85 ms │        273.26 / 277.68 ±4.89 / 286.66 ms │     no change │
│ QQuery 68 │        12.57 / 12.78 ±0.16 / 12.99 ms │           12.19 / 12.34 ±0.13 / 12.58 ms │     no change │
│ QQuery 69 │        58.06 / 61.96 ±5.07 / 71.93 ms │           56.32 / 57.26 ±0.57 / 57.98 ms │ +1.08x faster │
│ QQuery 70 │     105.08 / 108.28 ±2.23 / 111.94 ms │        108.50 / 111.39 ±4.02 / 119.21 ms │     no change │
│ QQuery 71 │        35.12 / 35.67 ±0.30 / 36.03 ms │           35.08 / 35.52 ±0.25 / 35.82 ms │     no change │
│ QQuery 72 │ 1752.61 / 1819.02 ±59.84 / 1928.13 ms │    1767.53 / 1799.64 ±36.60 / 1870.08 ms │     no change │
│ QQuery 73 │        11.08 / 12.43 ±2.13 / 16.68 ms │           10.82 / 11.04 ±0.16 / 11.29 ms │ +1.13x faster │
│ QQuery 74 │     181.96 / 186.26 ±3.00 / 190.40 ms │        175.91 / 182.95 ±5.00 / 188.40 ms │     no change │
│ QQuery 75 │     145.70 / 147.82 ±1.97 / 151.50 ms │        142.97 / 147.38 ±3.99 / 154.56 ms │     no change │
│ QQuery 76 │        35.64 / 35.85 ±0.15 / 36.05 ms │           35.35 / 35.97 ±0.46 / 36.48 ms │     no change │
│ QQuery 77 │        62.01 / 64.48 ±4.23 / 72.93 ms │           60.58 / 61.37 ±0.75 / 62.61 ms │     no change │
│ QQuery 78 │     176.13 / 184.00 ±7.14 / 194.93 ms │        172.60 / 177.29 ±5.62 / 188.31 ms │     no change │
│ QQuery 79 │        69.51 / 71.89 ±3.66 / 79.17 ms │           69.10 / 71.87 ±4.50 / 80.81 ms │     no change │
│ QQuery 80 │      97.89 / 100.20 ±2.04 / 103.85 ms │         99.09 / 101.44 ±2.14 / 104.15 ms │     no change │
│ QQuery 81 │        26.94 / 28.52 ±2.68 / 33.86 ms │           27.29 / 27.67 ±0.20 / 27.87 ms │     no change │
│ QQuery 82 │        17.74 / 17.93 ±0.12 / 18.10 ms │           17.44 / 17.77 ±0.31 / 18.14 ms │     no change │
│ QQuery 83 │        34.33 / 35.09 ±0.85 / 36.72 ms │           33.93 / 34.46 ±0.35 / 34.81 ms │     no change │
│ QQuery 84 │        30.52 / 31.91 ±2.13 / 36.14 ms │           30.68 / 32.29 ±2.38 / 37.00 ms │     no change │
│ QQuery 85 │     101.40 / 102.78 ±1.83 / 106.35 ms │        100.67 / 101.56 ±0.95 / 103.27 ms │     no change │
│ QQuery 86 │        26.63 / 27.10 ±0.32 / 27.58 ms │           26.44 / 26.72 ±0.18 / 26.96 ms │     no change │
│ QQuery 87 │        65.36 / 66.81 ±1.05 / 68.43 ms │           66.12 / 66.95 ±0.54 / 67.46 ms │     no change │
│ QQuery 88 │        60.27 / 60.84 ±0.35 / 61.29 ms │           60.34 / 60.81 ±0.35 / 61.21 ms │     no change │
│ QQuery 89 │        35.42 / 35.53 ±0.09 / 35.67 ms │           35.78 / 36.16 ±0.26 / 36.56 ms │     no change │
│ QQuery 90 │        16.90 / 18.35 ±2.75 / 23.85 ms │           16.79 / 16.94 ±0.18 / 17.25 ms │ +1.08x faster │
│ QQuery 91 │        42.27 / 42.57 ±0.35 / 43.22 ms │           42.22 / 42.56 ±0.26 / 42.82 ms │     no change │
│ QQuery 92 │        30.67 / 31.46 ±0.73 / 32.61 ms │           30.82 / 32.84 ±3.94 / 40.72 ms │     no change │
│ QQuery 93 │        52.44 / 53.35 ±0.84 / 54.45 ms │           50.99 / 52.74 ±1.55 / 55.23 ms │     no change │
│ QQuery 94 │        39.36 / 39.98 ±0.35 / 40.43 ms │           38.83 / 39.82 ±0.78 / 40.75 ms │     no change │
│ QQuery 95 │        81.90 / 84.00 ±2.40 / 88.52 ms │           81.02 / 82.16 ±0.85 / 83.12 ms │     no change │
│ QQuery 96 │        24.10 / 24.38 ±0.42 / 25.20 ms │           24.19 / 25.57 ±2.61 / 30.80 ms │     no change │
│ QQuery 97 │        52.26 / 53.11 ±0.69 / 54.11 ms │           52.34 / 53.96 ±1.56 / 55.88 ms │     no change │
│ QQuery 98 │        45.90 / 46.67 ±0.75 / 48.03 ms │           45.76 / 46.13 ±0.49 / 47.04 ms │     no change │
│ QQuery 99 │        67.39 / 68.96 ±1.71 / 72.27 ms │           67.10 / 67.39 ±0.21 / 67.65 ms │     no change │
└───────────┴───────────────────────────────────────┴──────────────────────────────────────────┴───────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━┓
┃ Benchmark Summary                                       ┃           ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━┩
│ Total Time (HEAD)                                       │ 9656.23ms │
│ Total Time (fix_single-distinct-groupby-memory-usage)   │ 9564.43ms │
│ Average Time (HEAD)                                     │   97.54ms │
│ Average Time (fix_single-distinct-groupby-memory-usage) │   96.61ms │
│ Queries Faster                                          │         7 │
│ Queries Slower                                          │         2 │
│ Queries with No Change                                  │        90 │
│ Queries with Failure                                    │         0 │
└─────────────────────────────────────────────────────────┴───────────┘

Resource Usage

tpcds — base (merge-base)

Metric Value
Wall time 50.0s
Peak memory 2.4 GiB
Avg memory 1.6 GiB
CPU user 208.1s
CPU sys 6.0s
Peak spill 0 B

tpcds — branch

Metric Value
Wall time 50.0s
Peak memory 2.2 GiB
Avg memory 1.5 GiB
CPU user 207.8s
CPU sys 5.9s
Peak spill 0 B

File an issue against this benchmark runner

@mkleen

mkleen commented Oct 17, 2026

Copy link
Copy Markdown
Contributor

@mohitgurav20 Thanks! Looks good at first glance. I’ll go ahead and start the review.

@mohitgurav20

Copy link
Copy Markdown
Contributor Author

@mkleen Just a quick ping on this — resolved the previous conflicts and re-synced with main, and CI is green across the board. Ready for review whenever you have a moment.

@mohitgurav20
mohitgurav20 requested a review from mkleen November 1, 2026 11:07

@mkleen mkleen 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.

The PR is a performance change. It rewrites less often to save memory and time. But it doesn't include any benchmark results showing that it actually improves anything.

@mohitgurav20

Copy link
Copy Markdown
Contributor Author

@mkleen sure sir ill be back back with the requirements

@mkleen

mkleen commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

My suggestion would be to narrow this PR down to just the config option, single_distinct_aggregation_prefer_memory, and leave the default rewrite behaviour as it is on main. This needs backup with benchmarks and proper documentation.

@mkleen

mkleen commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

So the new setting should lower the peak memory of single-DISTINCT aggregates, at the cost of runtime. We want to measure how much memory it actually saves and how much speed it costs.

@mkleen

mkleen commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

Here's a set of benchmark queries for the flag. They use the table from the #25932,
plus string and float columns, so they cover integers vs. non-native accumulators:

CREATE TABLE t AS
SELECT v % 2000                            AS g,      -- 2,000 groups
       v % 10                              AS g_few,  -- 10 groups
       (v * 48271) % 999983                AS x,      -- ~1M distinct ints
       CAST((v * 48271) % 999983 AS VARCHAR) AS s,    -- same values as strings
       CAST((v * 48271) % 999983 AS DOUBLE)  AS f,    -- same values as floats
       CAST(v % 100 AS SMALLINT)           AS si,     -- small-int, 100 distinct
       v % 1000                            AS y
FROM (SELECT unnest(generate_series(0, 3999999)) AS v);
  1. With GROUP BY, many groups (where the rewrite's memory cost shows most)
SELECT g, count(DISTINCT x) FROM t GROUP BY g;
SELECT g, sum(DISTINCT x)   FROM t GROUP BY g;
SELECT g, count(DISTINCT s) FROM t GROUP BY g;
SELECT g, avg(DISTINCT f)   FROM t GROUP BY g;
  1. With GROUP BY, few groups (each group's distinct set is large)
SELECT g_few, count(DISTINCT x) FROM t GROUP BY g_few;
SELECT g_few, sum(DISTINCT x)   FROM t GROUP BY g_few;
SELECT g_few, count(DISTINCT s) FROM t GROUP BY g_few;
  1. With companion aggregates (the rule also rewrites these)
SELECT g, sum(y), sum(DISTINCT x)             FROM t GROUP BY g;
SELECT g, count(*), count(DISTINCT x)         FROM t GROUP BY g;
SELECT g, min(y), max(y), count(DISTINCT s)   FROM t GROUP BY g;
  1. No GROUP BY (here the rewrite is the only way to parallelise the distinct)
SELECT count(DISTINCT x)  FROM t;
SELECT sum(DISTINCT x)    FROM t;
SELECT count(DISTINCT s)  FROM t;
SELECT count(DISTINCT si) FROM t;            -- small-int case
SELECT count(*), count(DISTINCT x) FROM t;

@github-actions github-actions Bot removed the core Core DataFusion crate label Nov 1, 2026
@mohitgurav20

mohitgurav20 commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor Author

@mkleen I've updated the PR following your suggestion.

It now only introduces the configuration flag datafusion.optimizer.single_distinct_aggregation_prefer_memory (defaults to false). All the earlier heuristic gating has been removed so default behavior on main is completely unchanged. We still keep the rewrite for aggregates with DistinctHandling::Unsupported (like approx_median) so correctness isn't affected.

I ran the 15 queries on a 4M row dataset using PeakRecordingPool (8 partitions). Here is a summary of what the numbers show:

Key Takeaways

  1. Where prefer_memory = true helps (up to 76% memory drop):

    • For GROUP BY queries with numeric distincts (e.g. sum(DISTINCT int), avg(DISTINCT float)), skipping the two-phase rewrite reduces peak memory by 60% to 76% (from ~194 MB down to ~46–76 MB) while running at basically the same speed (0.9x–1.1x).
    • For low-cardinality values like smallint, skipping the rewrite is actually 2.5x faster and uses 88% less memory because it avoids the repartitioning overhead.
  2. Why keeping default = false makes sense:

    • Strings: Without the two-phase rewrite, distinct string allocations pile up in the accumulators, increasing memory (+10% to +45%) and slowing down runtime by 2x–5x.
    • Queries without GROUP BY: The rewrite is currently DataFusion's way to parallelize un-grouped distinct work across threads. Disabling it forces the distinct work onto a single partition, leading to a 1.6x–3.4x slowdown on high cardinality data.

Click to view full benchmark numbers (15 queries, 4M rows)
Query Type Query prefer_memory=false (default) prefer_memory=true Peak Mem Delta Speed Ratio
GROUP BY (2000 groups) count(DISTINCT int) 148 ms / 187 MB 215 ms / 169 MB -9% 1.4x
GROUP BY (2000 groups) sum(DISTINCT int) 169 ms / 194 MB 180 ms / 77 MB -60% 1.1x
GROUP BY (2000 groups) count(DISTINCT str) 157 ms / 226 MB 853 ms / 327 MB +45% 5.4x
GROUP BY (2000 groups) avg(DISTINCT float) 155 ms / 194 MB 219 ms / 77 MB -60% 1.4x
GROUP BY (10 groups) sum(DISTINCT int) 131 ms / 194 MB 117 ms / 46 MB -76% 0.9x
Companion aggs sum(y), sum(DISTINCT x) 209 ms / 226 MB 183 ms / 77 MB -66% 0.9x
Companion aggs min(y), max(y), count(DISTINCT s) 200 ms / 267 MB 849 ms / 328 MB +23% 4.2x
No GROUP BY sum(DISTINCT int) 67 ms / 49 MB 112 ms / 72 MB +47% 1.7x
No GROUP BY count(DISTINCT str) 141 ms / 96 MB 476 ms / 329 MB +243% 3.4x
No GROUP BY count(DISTINCT smallint) 5.8 ms / 0.57 MB 2.3 ms / 0.07 MB -88% 0.4x

Overall, having the flag default to false keeps the fast parallel path intact for normal workloads, while giving users a solid knob when they need to keep peak memory down on large group-by queries.

Let me know if this looks good to you!

@mohitgurav20
mohitgurav20 requested a review from mkleen November 1, 2026 19:46
@mkleen

mkleen commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Great. So in which scenarios would switching of the rewrite makes sense? When does it significantly reduce memory consumption with only a minor impact on performance?

For GROUP BY queries with numeric distincts (e.g. sum(DISTINCT int), avg(DISTINCT float)), skipping the two-phase rewrite reduces peak memory by 60% to 76% (from ~194 MB down to ~46–76 MB) while running at basically the same speed (0.9x–1.1x).

Ok, this is the part i would focus on.

@mohitgurav20

Copy link
Copy Markdown
Contributor Author

From checking the execution plans and benchmark numbers, turning off the rewrite (prefer_memory = true) gives a big advantage mainly in two cases:

  1. GROUP BY queries on numeric data (especially with companion aggregates):
    This showed the biggest memory drop. In queries like SELECT y, sum(y), sum(DISTINCT x) and SELECT y, sum(DISTINCT x), peak memory dropped by 60% to 76% (from around 194 MB down to 46–77 MB), and the runtime was basically identical or even slightly faster (183 ms vs 209 ms).

    The reason is that the 2-phase rewrite creates an extra intermediate aggregate grouped by both (y, x) and shuffles that across partitions. But for numeric types like ints and floats, values are small and fixed-size. With single-phase, we only maintain the y group table and handle distinct values in place, so we completely avoid materializing and shuffling that intermediate (y, x) table.

  2. Low cardinality columns (like smallint or categorical IDs):
    For count(DISTINCT smallint), single-phase was 2.5x faster (2.3 ms vs 5.8 ms) and used 88% less memory (0.07 MB vs 0.57 MB). When there are very few distinct values, setting up a 2-phase aggregation and repartitioning is just extra overhead.

On the other hand, the benchmarks also clearly showed why the rewrite should stay enabled by default:

  • Queries without GROUP BY: Without the rewrite, DataFusion runs the distinct aggregation on a single partition/thread, which causes a 1.6x to 3.4x slowdown on larger datasets.
  • Strings: Storing distinct strings without the early 2-phase reduction causes a lot of heap allocations in the accumulators, which actually increases peak memory (+10% to +45%) and makes it much slower.

So the flag works best when users have memory-heavy GROUP BY queries over numeric or low-cardinality data, where they can save up to ~75% peak memory with almost zero performance impact.

@mkleen

mkleen commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

Can we implement the flag in a way, that the memory comsumptions gets better without having any real bad performance impacts and avoid the cases where it gets worse ?

@mohitgurav20

Copy link
Copy Markdown
Contributor Author

Yes, we can definitely do that.

From the benchmarks, the only cases that got worse were:

  1. Queries without GROUP BY (because they lose multi-threading).
  2. String columns (because of per-string memory allocations).

So under the flag, we can only skip the rewrite if:

  • The query has a GROUP BY (!aggr.group_expr.is_empty())
  • The distinct column is a fixed numeric/primitive type (not strings)

That way, strings and queries without GROUP BY will continue using the 2-phase rewrite as normal, and only numeric GROUP BY queries will skip it—giving the 60%–76% memory savings with no real performance hit.

I can push this change if that sounds good to you!

@github-actions github-actions Bot removed the auto detected api change Auto detected API change label Nov 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

common Related to common crate documentation Improvements or additions to documentation optimizer Optimizer rules sqllogictest SQL Logic Tests (.slt)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

sum(DISTINCT x) with GROUP BY uses twice the memory or more

5 participants