Skip to content

perf: add opt-in native grouped integer DISTINCT counts - #25988

Open
QinXi-ai wants to merge 6 commits into
apache:mainfrom
QinXi-ai:codex/25936-numeric-distinct-count
Open

QinXi-ai wants to merge 6 commits into
apache:mainfrom
QinXi-ai:codex/25936-numeric-distinct-count

Conversation

@QinXi-ai

@QinXi-ai QinXi-ai commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Which issue does this PR close?

Closes #25936.

Rationale for this change

Grouped integer count(DISTINCT x) can use its native GroupsAccumulator to avoid an extra aggregate over distinct (group, value) pairs. This helps the original single-target-partition workload, but the choice also affects spilling and performance on other data shapes.

The native plan is now opt-in. The default keeps the existing two-phase rewrite. Under a 1 MiB memory limit, the reviewer's query with two groups and 100,000 distinct values completes with the rewrite and returns 2, 100000; the native plan runs out of memory. Native DISTINCT must fit each group's distinct values in memory, including when merging spilled or partial states.

What changes are included in this PR?

Add datafusion.optimizer.single_distinct_prefer_native, default false. When enabled, grouped all-DISTINCT aggregates retain the native plan only if:

  • execution.target_partitions == 1;
  • all aggregates share one DISTINCT argument;
  • every aggregate explicitly reports specialized GroupsAccumulator support for its argument types.

Unknown support preserves the rewrite. Integer DISTINCT counts currently qualify; string and floating-point arguments, global aggregates, mixed aggregates and multiple target partitions keep their existing behavior.

The earlier GKE ClickBench comparison regressed with native parallel plans, so multiple target partitions continue to distribute deduplication by both the group key and distinct value.

One target partition can still have multiple input partitions. UNION ALL and a table created with four partitions can use Partial → Coalesce → Final and rebuild the DISTINCT set in Final. This is covered by execution tests and physical-plan snapshots.

Add a ten-query SQL benchmark suite covering argument types, grouping-key types, cardinality, skew and duplicates. Q10 has one million groups with four copies of the same value per group at the default four million rows. Native execution probes both the group table and the distinct set on every row; the rewrite's outer aggregate only sees deduplicated pairs. This is an unfavorable case for the native path, and the logical rule has no statistics to cost it.

This overlaps with the option proposed in #26000. prefer_native describes the plan choice without promising lower memory use; the two PRs should converge on one setting.

Local comparison, November 7

Compared main 636590b with review-fix commit 4a0bacd4, flag off and on, on Linux (Xeon Gold 6238T, CPU affinity 0–7), Rust 1.99.1, release-nonlto, four million rows, greedy / 1 GiB. All ten queries ran at 1, 4 and 12 target partitions in three rounds, reversing version order in the second round. Each round had six iterations per query, with the first discarded: 15 retained samples per version and configuration. All result assertions passed. The main executable was reused from the November 2 build; the review fix was freshly rebuilt, and all versions used the same updated ten-query suite. No builds ran during timing.

Single-partition medians:

Case Main Flag off (default) Flag on On vs off elapsed time
Q01: Int64, 2,000 groups, high NDV 448.97 ms 424.17 ms 305.27 ms −28.0%
Q02: Int64, 2,000 groups, low NDV 102.96 ms 101.23 ms 79.91 ms −21.1%
Q10: 1M groups, four identical values per group 316.79 ms 284.87 ms 398.12 ms +39.8%

Q10 reproduces the reviewer's regression. Its memory-pool peak also rises from 69.88 MiB with the flag off to 95.88 MiB with it on. Q01 goes the other way, from 191.45 to 168.17 MiB. Both the runtime and memory tradeoffs are reasons to keep this opt-in.

The primary comparison is off/on in the same executable. Main and flag-off use the same plans but have timing differences on this shared host. At four and twelve target partitions both flag values keep the rewrite; observed off/on median differences range from −8.0% to +11.2%. Separate physical-plan checks for Q01 and Q10 passed for all three versions at all three partition settings (18 checks).

What is the testing strategy for this PR?

SQL tests cover the default and both flag values in one session, integer types and NULLs, the low-memory spill reproducer, native plan selection, UNION ALL, a pre-partitioned table, and the rewrite at four target partitions. The configuration documentation and information-schema snapshots include the new default.

On Linux at 4a0bacd4, formatting, generated configuration docs, Prettier, strict all-targets/all-features Clippy and the full dev/rust_lint.sh passed. The extended workspace run passed 13,395 Rust tests (8 ignored, none failed) and all 547 SQL files. The CLI run passed 112 tests, and the focused SQL run passed all seven files.

Are there any user-facing changes?

The new setting lets users opt into native grouped integer DISTINCT counts with one target partition. Default planning stays unchanged.

@github-actions github-actions Bot added optimizer Optimizer rules sqllogictest SQL Logic Tests (.slt) labels Oct 3, 2026
@codecov-commenter

codecov-commenter commented Oct 3, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.00000% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.73%. Comparing base (416002a) to head (2d74893).
⚠️ Report is 352 commits behind head on main.

Files with missing lines Patch % Lines
...fusion/optimizer/src/single_distinct_to_groupby.rs 92.00% 0 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #25988      +/-   ##
==========================================
+ Coverage   82.59%   82.73%   +0.14%     
==========================================
  Files        1145     1147       +2     
  Lines      444096   449377    +5281     
  Branches   444096   449377    +5281     
==========================================
+ Hits       366806   371798    +4992     
+ Misses      55021    54920     -101     
- Partials    22269    22659     +390     

☔ 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.

@Dandandan

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-c6034844489-3114-258bh 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 codex/25936-numeric-distinct-count (3ae5962) to 416002a (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-c6034844489-3116-bvhgp 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 codex/25936-numeric-distinct-count (3ae5962) to 416002a (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-c6034844489-3115-s2ld5 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 codex/25936-numeric-distinct-count (3ae5962) to 416002a (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 codex/25936-numeric-distinct-count (3ae5962) to 416002a (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 codex_25936-numeric-distinct-count
--------------------
Benchmark tpch_sf1.json
--------------------
┏━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Query     ┃     HEAD ┃ codex_25936-numeric-distinct-count ┃        Change ┃
┡━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ QQuery 1  │ 40.80 ms │                           40.71 ms │     no change │
│ QQuery 2  │ 18.40 ms │                           18.46 ms │     no change │
│ QQuery 3  │ 28.83 ms │                           28.60 ms │     no change │
│ QQuery 4  │ 17.61 ms │                           17.32 ms │     no change │
│ QQuery 5  │ 35.54 ms │                           35.10 ms │     no change │
│ QQuery 6  │ 16.33 ms │                           16.40 ms │     no change │
│ QQuery 7  │ 41.28 ms │                           41.31 ms │     no change │
│ QQuery 8  │ 40.50 ms │                           40.51 ms │     no change │
│ QQuery 9  │ 48.73 ms │                           48.40 ms │     no change │
│ QQuery 10 │ 40.49 ms │                           40.61 ms │     no change │
│ QQuery 11 │ 13.84 ms │                           13.91 ms │     no change │
│ QQuery 12 │ 21.04 ms │                           21.06 ms │     no change │
│ QQuery 13 │ 40.43 ms │                           40.39 ms │     no change │
│ QQuery 14 │ 24.58 ms │                           24.62 ms │     no change │
│ QQuery 15 │ 31.27 ms │                           30.93 ms │     no change │
│ QQuery 16 │ 14.10 ms │                           12.74 ms │ +1.11x faster │
│ QQuery 17 │ 74.69 ms │                           73.12 ms │     no change │
│ QQuery 18 │ 62.07 ms │                           61.77 ms │     no change │
│ QQuery 19 │ 31.84 ms │                           31.79 ms │     no change │
│ QQuery 20 │ 32.07 ms │                           32.13 ms │     no change │
│ QQuery 21 │ 56.30 ms │                           54.99 ms │     no change │
│ QQuery 22 │ 13.96 ms │                           13.45 ms │     no change │
└───────────┴──────────┴────────────────────────────────────┴───────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┓
┃ Benchmark Summary                                 ┃          ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━┩
│ Total Time (HEAD)                                 │ 744.70ms │
│ Total Time (codex_25936-numeric-distinct-count)   │ 738.33ms │
│ Average Time (HEAD)                               │  33.85ms │
│ Average Time (codex_25936-numeric-distinct-count) │  33.56ms │
│ 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 codex_25936-numeric-distinct-count
--------------------
Benchmark tpch_sf1.json
--------------------
┏━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Query     ┃                           HEAD ┃ codex_25936-numeric-distinct-count ┃        Change ┃
┡━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ QQuery 1  │ 40.80 / 41.94 ±1.30 / 43.60 ms │     40.71 / 42.38 ±1.04 / 43.54 ms │     no change │
│ QQuery 2  │ 18.40 / 18.86 ±0.29 / 19.23 ms │     18.46 / 18.94 ±0.48 / 19.70 ms │     no change │
│ QQuery 3  │ 28.83 / 30.00 ±1.55 / 33.05 ms │     28.60 / 29.01 ±0.40 / 29.76 ms │     no change │
│ QQuery 4  │ 17.61 / 18.06 ±0.51 / 18.87 ms │     17.32 / 17.79 ±0.84 / 19.47 ms │     no change │
│ QQuery 5  │ 35.54 / 36.62 ±1.22 / 38.73 ms │     35.10 / 35.92 ±1.03 / 37.94 ms │     no change │
│ QQuery 6  │ 16.33 / 16.89 ±0.88 / 18.64 ms │     16.40 / 16.46 ±0.05 / 16.52 ms │     no change │
│ QQuery 7  │ 41.28 / 42.59 ±0.88 / 43.66 ms │     41.31 / 42.40 ±0.84 / 43.77 ms │     no change │
│ QQuery 8  │ 40.50 / 40.68 ±0.22 / 41.07 ms │     40.51 / 40.78 ±0.25 / 41.16 ms │     no change │
│ QQuery 9  │ 48.73 / 50.17 ±1.01 / 51.53 ms │     48.40 / 50.63 ±1.32 / 52.46 ms │     no change │
│ QQuery 10 │ 40.49 / 40.81 ±0.38 / 41.55 ms │     40.61 / 41.25 ±0.96 / 43.16 ms │     no change │
│ QQuery 11 │ 13.84 / 14.53 ±0.93 / 16.38 ms │     13.91 / 13.99 ±0.06 / 14.06 ms │     no change │
│ QQuery 12 │ 21.04 / 21.52 ±0.39 / 22.17 ms │     21.06 / 21.49 ±0.30 / 21.91 ms │     no change │
│ QQuery 13 │ 40.43 / 40.92 ±0.77 / 42.44 ms │     40.39 / 40.71 ±0.26 / 41.03 ms │     no change │
│ QQuery 14 │ 24.58 / 25.24 ±0.95 / 27.14 ms │     24.62 / 24.76 ±0.13 / 24.97 ms │     no change │
│ QQuery 15 │ 31.27 / 31.86 ±0.65 / 32.94 ms │     30.93 / 31.56 ±0.87 / 33.27 ms │     no change │
│ QQuery 16 │ 14.10 / 14.22 ±0.12 / 14.41 ms │     12.74 / 13.04 ±0.38 / 13.78 ms │ +1.09x faster │
│ QQuery 17 │ 74.69 / 75.53 ±1.21 / 77.86 ms │     73.12 / 75.83 ±3.12 / 81.71 ms │     no change │
│ QQuery 18 │ 62.07 / 65.88 ±4.26 / 73.63 ms │     61.77 / 63.61 ±1.72 / 66.33 ms │     no change │
│ QQuery 19 │ 31.84 / 32.53 ±0.86 / 34.16 ms │     31.79 / 32.58 ±1.20 / 34.96 ms │     no change │
│ QQuery 20 │ 32.07 / 32.31 ±0.34 / 32.98 ms │     32.13 / 32.43 ±0.32 / 32.86 ms │     no change │
│ QQuery 21 │ 56.30 / 56.58 ±0.23 / 56.90 ms │     54.99 / 55.46 ±0.48 / 56.07 ms │     no change │
│ QQuery 22 │ 13.96 / 14.05 ±0.06 / 14.13 ms │     13.45 / 13.83 ±0.24 / 14.08 ms │     no change │
└───────────┴────────────────────────────────┴────────────────────────────────────┴───────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┓
┃ Benchmark Summary                                 ┃          ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━┩
│ Total Time (HEAD)                                 │ 761.77ms │
│ Total Time (codex_25936-numeric-distinct-count)   │ 754.83ms │
│ Average Time (HEAD)                               │  34.63ms │
│ Average Time (codex_25936-numeric-distinct-count) │  34.31ms │
│ 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.3 GiB
Avg memory 510.0 MiB
CPU user 21.3s
CPU sys 1.8s
Peak spill 0 B

tpch — branch

Metric Value
Wall time 5.0s
Peak memory 1.3 GiB
Avg memory 506.2 MiB
CPU user 21.1s
CPU sys 1.8s
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 codex/25936-numeric-distinct-count (3ae5962) to 416002a (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 codex_25936-numeric-distinct-count
--------------------
Benchmark tpcds_sf1.json
--------------------
┏━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Query     ┃       HEAD ┃ codex_25936-numeric-distinct-count ┃        Change ┃
┡━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ QQuery 1  │    5.26 ms │                            5.19 ms │     no change │
│ QQuery 2  │   80.44 ms │                           79.07 ms │     no change │
│ QQuery 3  │   28.70 ms │                           28.45 ms │     no change │
│ QQuery 4  │  438.59 ms │                          436.01 ms │     no change │
│ QQuery 5  │   49.43 ms │                           50.07 ms │     no change │
│ QQuery 6  │   34.78 ms │                           35.60 ms │     no change │
│ QQuery 7  │   73.59 ms │                           73.45 ms │     no change │
│ QQuery 8  │   35.94 ms │                           35.54 ms │     no change │
│ QQuery 9  │   51.71 ms │                           51.32 ms │     no change │
│ QQuery 10 │   61.17 ms │                           61.16 ms │     no change │
│ QQuery 11 │  260.24 ms │                          266.18 ms │     no change │
│ QQuery 12 │   28.76 ms │                           27.86 ms │     no change │
│ QQuery 13 │  115.77 ms │                          116.60 ms │     no change │
│ QQuery 14 │  387.65 ms │                          390.22 ms │     no change │
│ QQuery 15 │   52.30 ms │                           52.43 ms │     no change │
│ QQuery 16 │    6.18 ms │                            6.04 ms │     no change │
│ QQuery 17 │   77.58 ms │                           77.17 ms │     no change │
│ QQuery 18 │  102.75 ms │                          101.42 ms │     no change │
│ QQuery 19 │   41.10 ms │                           41.17 ms │     no change │
│ QQuery 20 │   35.35 ms │                           34.69 ms │     no change │
│ QQuery 21 │   17.06 ms │                           16.57 ms │     no change │
│ QQuery 22 │   63.60 ms │                           63.72 ms │     no change │
│ QQuery 23 │  307.69 ms │                          302.81 ms │     no change │
│ QQuery 24 │  189.59 ms │                          188.59 ms │     no change │
│ QQuery 25 │  106.05 ms │                          105.13 ms │     no change │
│ QQuery 26 │   47.31 ms │                           47.23 ms │     no change │
│ QQuery 27 │    5.73 ms │                            5.69 ms │     no change │
│ QQuery 28 │   59.67 ms │                           55.03 ms │ +1.08x faster │
│ QQuery 29 │   93.72 ms │                           93.13 ms │     no change │
│ QQuery 30 │   31.93 ms │                           32.75 ms │     no change │
│ QQuery 31 │  107.14 ms │                          106.10 ms │     no change │
│ QQuery 32 │   19.28 ms │                           19.39 ms │     no change │
│ QQuery 33 │   36.62 ms │                           35.83 ms │     no change │
│ QQuery 34 │    9.75 ms │                            9.61 ms │     no change │
│ QQuery 35 │   70.41 ms │                           70.35 ms │     no change │
│ QQuery 36 │    5.42 ms │                            5.45 ms │     no change │
│ QQuery 37 │    6.49 ms │                            6.47 ms │     no change │
│ QQuery 38 │   60.65 ms │                           60.61 ms │     no change │
│ QQuery 39 │   72.31 ms │                           72.75 ms │     no change │
│ QQuery 40 │   22.79 ms │                           22.96 ms │     no change │
│ QQuery 41 │   11.42 ms │                           10.98 ms │     no change │
│ QQuery 42 │   23.67 ms │                           22.99 ms │     no change │
│ QQuery 43 │    4.60 ms │                            4.56 ms │     no change │
│ QQuery 44 │    8.69 ms │                            8.61 ms │     no change │
│ QQuery 45 │   37.71 ms │                           36.05 ms │     no change │
│ QQuery 46 │   11.41 ms │                           11.37 ms │     no change │
│ QQuery 47 │  218.41 ms │                          218.83 ms │     no change │
│ QQuery 48 │   94.41 ms │                           94.22 ms │     no change │
│ QQuery 49 │   68.97 ms │                           68.51 ms │     no change │
│ QQuery 50 │   57.07 ms │                           56.59 ms │     no change │
│ QQuery 51 │   93.18 ms │                           92.53 ms │     no change │
│ QQuery 52 │   23.75 ms │                           23.68 ms │     no change │
│ QQuery 53 │   28.88 ms │                           28.59 ms │     no change │
│ QQuery 54 │   53.41 ms │                           53.01 ms │     no change │
│ QQuery 55 │   23.58 ms │                           23.10 ms │     no change │
│ QQuery 56 │   37.96 ms │                           37.45 ms │     no change │
│ QQuery 57 │  169.33 ms │                          167.43 ms │     no change │
│ QQuery 58 │  107.26 ms │                          107.52 ms │     no change │
│ QQuery 59 │  116.09 ms │                          115.05 ms │     no change │
│ QQuery 60 │   38.12 ms │                           37.82 ms │     no change │
│ QQuery 61 │   11.03 ms │                           11.24 ms │     no change │
│ QQuery 62 │   43.86 ms │                           44.33 ms │     no change │
│ QQuery 63 │   28.96 ms │                           28.87 ms │     no change │
│ QQuery 64 │  358.35 ms │                          355.65 ms │     no change │
│ QQuery 65 │  128.71 ms │                          128.23 ms │     no change │
│ QQuery 66 │   74.38 ms │                           74.21 ms │     no change │
│ QQuery 67 │  249.51 ms │                          248.09 ms │     no change │
│ QQuery 68 │   11.77 ms │                           11.37 ms │     no change │
│ QQuery 69 │   55.16 ms │                           55.30 ms │     no change │
│ QQuery 70 │  103.21 ms │                          102.35 ms │     no change │
│ QQuery 71 │   34.66 ms │                           34.26 ms │     no change │
│ QQuery 72 │ 1742.26 ms │                         1632.70 ms │ +1.07x faster │
│ QQuery 73 │    9.75 ms │                            9.63 ms │     no change │
│ QQuery 74 │  156.84 ms │                          150.79 ms │     no change │
│ QQuery 75 │  137.86 ms │                          138.42 ms │     no change │
│ QQuery 76 │   33.89 ms │                           33.33 ms │     no change │
│ QQuery 77 │   58.42 ms │                           59.16 ms │     no change │
│ QQuery 78 │  159.62 ms │                          159.97 ms │     no change │
│ QQuery 79 │   65.27 ms │                           65.51 ms │     no change │
│ QQuery 80 │   94.60 ms │                           93.41 ms │     no change │
│ QQuery 81 │   24.69 ms │                           25.34 ms │     no change │
│ QQuery 82 │   15.97 ms │                           15.96 ms │     no change │
│ QQuery 83 │   32.90 ms │                           32.68 ms │     no change │
│ QQuery 84 │   28.91 ms │                           29.07 ms │     no change │
│ QQuery 85 │  101.11 ms │                          100.52 ms │     no change │
│ QQuery 86 │   25.44 ms │                           24.72 ms │     no change │
│ QQuery 87 │   60.67 ms │                           61.07 ms │     no change │
│ QQuery 88 │   59.40 ms │                           59.30 ms │     no change │
│ QQuery 89 │   34.74 ms │                           34.81 ms │     no change │
│ QQuery 90 │   15.93 ms │                           15.93 ms │     no change │
│ QQuery 91 │   43.74 ms │                           43.13 ms │     no change │
│ QQuery 92 │   29.03 ms │                           28.61 ms │     no change │
│ QQuery 93 │   48.67 ms │                           48.34 ms │     no change │
│ QQuery 94 │   38.47 ms │                           37.39 ms │     no change │
│ QQuery 95 │   79.66 ms │                           78.63 ms │     no change │
│ QQuery 96 │   23.60 ms │                           23.31 ms │     no change │
│ QQuery 97 │   50.55 ms │                           50.35 ms │     no change │
│ QQuery 98 │   42.31 ms │                           42.35 ms │     no change │
│ QQuery 99 │   65.25 ms │                           65.13 ms │     no change │
└───────────┴────────────┴────────────────────────────────────┴───────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━┓
┃ Benchmark Summary                                 ┃           ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━┩
│ Total Time (HEAD)                                 │ 8907.58ms │
│ Total Time (codex_25936-numeric-distinct-count)   │ 8762.21ms │
│ Average Time (HEAD)                               │   89.98ms │
│ Average Time (codex_25936-numeric-distinct-count) │   88.51ms │
│ 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 codex_25936-numeric-distinct-count
--------------------
Benchmark tpcds_sf1.json
--------------------
┏━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Query     ┃                                  HEAD ┃    codex_25936-numeric-distinct-count ┃        Change ┃
┡━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ QQuery 1  │           5.26 / 5.83 ±0.98 / 7.77 ms │           5.19 / 5.78 ±1.05 / 7.87 ms │     no change │
│ QQuery 2  │        80.44 / 80.86 ±0.33 / 81.43 ms │        79.07 / 79.77 ±0.42 / 80.32 ms │     no change │
│ QQuery 3  │        28.70 / 28.81 ±0.12 / 29.04 ms │        28.45 / 28.54 ±0.10 / 28.71 ms │     no change │
│ QQuery 4  │     438.59 / 441.34 ±2.49 / 445.47 ms │     436.01 / 439.02 ±1.91 / 440.95 ms │     no change │
│ QQuery 5  │        49.43 / 51.87 ±2.73 / 57.20 ms │        50.07 / 50.51 ±0.33 / 51.10 ms │     no change │
│ QQuery 6  │        34.78 / 35.63 ±0.56 / 36.44 ms │        35.60 / 36.19 ±0.51 / 36.99 ms │     no change │
│ QQuery 7  │        73.59 / 74.47 ±0.61 / 75.18 ms │        73.45 / 74.20 ±0.49 / 74.98 ms │     no change │
│ QQuery 8  │        35.94 / 36.25 ±0.17 / 36.43 ms │        35.54 / 35.83 ±0.31 / 36.36 ms │     no change │
│ QQuery 9  │        51.71 / 56.63 ±4.29 / 64.58 ms │        51.32 / 53.71 ±2.74 / 58.95 ms │ +1.05x faster │
│ QQuery 10 │        61.17 / 61.58 ±0.44 / 62.41 ms │        61.16 / 61.67 ±0.44 / 62.31 ms │     no change │
│ QQuery 11 │     260.24 / 267.05 ±5.78 / 276.44 ms │     266.18 / 270.75 ±3.34 / 276.22 ms │     no change │
│ QQuery 12 │        28.76 / 29.52 ±0.46 / 30.12 ms │        27.86 / 28.46 ±0.35 / 28.86 ms │     no change │
│ QQuery 13 │     115.77 / 118.14 ±1.97 / 121.69 ms │     116.60 / 117.66 ±0.90 / 119.09 ms │     no change │
│ QQuery 14 │     387.65 / 393.04 ±4.08 / 398.76 ms │     390.22 / 393.45 ±3.13 / 398.07 ms │     no change │
│ QQuery 15 │        52.30 / 54.64 ±2.37 / 59.15 ms │        52.43 / 53.17 ±0.62 / 53.90 ms │     no change │
│ QQuery 16 │           6.18 / 6.31 ±0.19 / 6.68 ms │           6.04 / 6.24 ±0.28 / 6.79 ms │     no change │
│ QQuery 17 │        77.58 / 79.40 ±1.99 / 82.97 ms │        77.17 / 78.82 ±1.70 / 82.05 ms │     no change │
│ QQuery 18 │     102.75 / 103.52 ±0.74 / 104.88 ms │     101.42 / 102.85 ±1.12 / 104.34 ms │     no change │
│ QQuery 19 │        41.10 / 41.42 ±0.57 / 42.56 ms │        41.17 / 41.42 ±0.22 / 41.83 ms │     no change │
│ QQuery 20 │        35.35 / 36.08 ±0.45 / 36.61 ms │        34.69 / 35.69 ±0.87 / 37.29 ms │     no change │
│ QQuery 21 │        17.06 / 17.62 ±0.75 / 19.07 ms │        16.57 / 17.06 ±0.36 / 17.66 ms │     no change │
│ QQuery 22 │        63.60 / 64.65 ±0.75 / 65.56 ms │        63.72 / 64.15 ±0.27 / 64.51 ms │     no change │
│ QQuery 23 │     307.69 / 310.54 ±2.35 / 314.52 ms │     302.81 / 309.46 ±6.03 / 320.22 ms │     no change │
│ QQuery 24 │     189.59 / 194.19 ±4.68 / 202.62 ms │     188.59 / 192.09 ±2.61 / 194.91 ms │     no change │
│ QQuery 25 │     106.05 / 107.75 ±1.46 / 109.73 ms │     105.13 / 107.49 ±1.28 / 108.85 ms │     no change │
│ QQuery 26 │        47.31 / 47.75 ±0.29 / 48.06 ms │        47.23 / 47.43 ±0.27 / 47.95 ms │     no change │
│ QQuery 27 │           5.73 / 5.91 ±0.22 / 6.31 ms │           5.69 / 6.00 ±0.23 / 6.39 ms │     no change │
│ QQuery 28 │        59.67 / 60.82 ±1.11 / 62.89 ms │        55.03 / 57.69 ±2.53 / 61.13 ms │ +1.05x faster │
│ QQuery 29 │       93.72 / 96.38 ±3.72 / 103.57 ms │        93.13 / 95.01 ±1.35 / 96.82 ms │     no change │
│ QQuery 30 │        31.93 / 32.70 ±0.75 / 34.07 ms │        32.75 / 34.51 ±2.00 / 38.26 ms │  1.06x slower │
│ QQuery 31 │     107.14 / 107.84 ±0.52 / 108.47 ms │     106.10 / 108.44 ±2.02 / 111.50 ms │     no change │
│ QQuery 32 │        19.28 / 19.65 ±0.32 / 20.20 ms │        19.39 / 19.84 ±0.25 / 20.13 ms │     no change │
│ QQuery 33 │        36.62 / 38.59 ±3.29 / 45.16 ms │        35.83 / 36.54 ±0.54 / 37.49 ms │ +1.06x faster │
│ QQuery 34 │         9.75 / 10.49 ±0.60 / 11.53 ms │         9.61 / 12.03 ±3.63 / 19.19 ms │  1.15x slower │
│ QQuery 35 │        70.41 / 70.98 ±0.65 / 72.13 ms │        70.35 / 71.52 ±1.29 / 73.44 ms │     no change │
│ QQuery 36 │           5.42 / 5.58 ±0.23 / 6.03 ms │           5.45 / 5.57 ±0.20 / 5.97 ms │     no change │
│ QQuery 37 │           6.49 / 6.61 ±0.11 / 6.80 ms │           6.47 / 6.54 ±0.06 / 6.63 ms │     no change │
│ QQuery 38 │        60.65 / 61.05 ±0.38 / 61.61 ms │        60.61 / 61.40 ±0.94 / 63.22 ms │     no change │
│ QQuery 39 │        72.31 / 75.46 ±3.14 / 81.44 ms │        72.75 / 74.92 ±2.99 / 80.82 ms │     no change │
│ QQuery 40 │        22.79 / 23.63 ±0.44 / 24.10 ms │        22.96 / 23.35 ±0.50 / 24.25 ms │     no change │
│ QQuery 41 │        11.42 / 11.53 ±0.07 / 11.65 ms │        10.98 / 11.18 ±0.18 / 11.41 ms │     no change │
│ QQuery 42 │        23.67 / 24.32 ±0.49 / 24.95 ms │        22.99 / 23.43 ±0.38 / 23.94 ms │     no change │
│ QQuery 43 │           4.60 / 4.81 ±0.23 / 5.26 ms │           4.56 / 4.64 ±0.13 / 4.90 ms │     no change │
│ QQuery 44 │          8.69 / 9.37 ±1.04 / 11.45 ms │           8.61 / 8.65 ±0.05 / 8.73 ms │ +1.08x faster │
│ QQuery 45 │        37.71 / 38.40 ±0.43 / 39.03 ms │        36.05 / 37.20 ±1.14 / 39.40 ms │     no change │
│ QQuery 46 │        11.41 / 11.70 ±0.26 / 12.03 ms │        11.37 / 11.94 ±0.49 / 12.69 ms │     no change │
│ QQuery 47 │     218.41 / 221.82 ±2.59 / 224.96 ms │     218.83 / 221.34 ±2.97 / 226.72 ms │     no change │
│ QQuery 48 │        94.41 / 96.71 ±1.99 / 99.87 ms │       94.22 / 95.75 ±2.27 / 100.25 ms │     no change │
│ QQuery 49 │        68.97 / 70.39 ±1.78 / 73.87 ms │        68.51 / 69.91 ±1.42 / 72.64 ms │     no change │
│ QQuery 50 │        57.07 / 58.03 ±1.08 / 60.08 ms │        56.59 / 57.35 ±0.55 / 58.28 ms │     no change │
│ QQuery 51 │        93.18 / 95.05 ±1.76 / 98.13 ms │       92.53 / 95.59 ±3.20 / 101.63 ms │     no change │
│ QQuery 52 │        23.75 / 24.18 ±0.35 / 24.58 ms │        23.68 / 23.84 ±0.12 / 24.02 ms │     no change │
│ QQuery 53 │        28.88 / 28.95 ±0.06 / 29.05 ms │        28.59 / 29.48 ±1.08 / 31.62 ms │     no change │
│ QQuery 54 │        53.41 / 55.85 ±4.48 / 64.80 ms │        53.01 / 53.55 ±0.71 / 54.95 ms │     no change │
│ QQuery 55 │        23.58 / 24.26 ±0.53 / 24.93 ms │        23.10 / 23.76 ±0.96 / 25.64 ms │     no change │
│ QQuery 56 │        37.96 / 38.31 ±0.44 / 39.14 ms │        37.45 / 37.74 ±0.24 / 38.08 ms │     no change │
│ QQuery 57 │     169.33 / 170.22 ±1.00 / 172.05 ms │     167.43 / 170.11 ±2.83 / 175.09 ms │     no change │
│ QQuery 58 │     107.26 / 109.56 ±1.31 / 111.08 ms │     107.52 / 109.09 ±1.44 / 111.52 ms │     no change │
│ QQuery 59 │     116.09 / 117.67 ±2.09 / 121.75 ms │     115.05 / 117.01 ±2.71 / 122.40 ms │     no change │
│ QQuery 60 │        38.12 / 38.62 ±0.41 / 39.31 ms │        37.82 / 38.67 ±0.56 / 39.58 ms │     no change │
│ QQuery 61 │        11.03 / 11.38 ±0.46 / 12.29 ms │        11.24 / 11.50 ±0.23 / 11.93 ms │     no change │
│ QQuery 62 │        43.86 / 44.49 ±0.38 / 44.95 ms │        44.33 / 44.68 ±0.44 / 45.54 ms │     no change │
│ QQuery 63 │        28.96 / 29.12 ±0.14 / 29.32 ms │        28.87 / 29.20 ±0.28 / 29.66 ms │     no change │
│ QQuery 64 │     358.35 / 363.58 ±7.12 / 376.67 ms │     355.65 / 359.35 ±3.66 / 366.28 ms │     no change │
│ QQuery 65 │     128.71 / 130.84 ±2.44 / 135.16 ms │     128.23 / 130.13 ±1.54 / 131.99 ms │     no change │
│ QQuery 66 │        74.38 / 75.99 ±1.69 / 78.98 ms │        74.21 / 75.67 ±1.70 / 79.00 ms │     no change │
│ QQuery 67 │     249.51 / 254.56 ±4.31 / 260.79 ms │     248.09 / 253.18 ±3.07 / 256.74 ms │     no change │
│ QQuery 68 │        11.77 / 12.05 ±0.26 / 12.51 ms │        11.37 / 11.63 ±0.21 / 12.02 ms │     no change │
│ QQuery 69 │        55.16 / 55.84 ±0.43 / 56.35 ms │        55.30 / 58.31 ±5.12 / 68.52 ms │     no change │
│ QQuery 70 │     103.21 / 103.70 ±0.65 / 104.95 ms │     102.35 / 103.81 ±1.25 / 105.93 ms │     no change │
│ QQuery 71 │        34.66 / 38.02 ±4.81 / 47.58 ms │        34.26 / 34.92 ±0.92 / 36.69 ms │ +1.09x faster │
│ QQuery 72 │ 1742.26 / 1796.84 ±65.94 / 1926.41 ms │ 1632.70 / 1760.71 ±78.58 / 1877.96 ms │     no change │
│ QQuery 73 │         9.75 / 10.91 ±1.10 / 12.38 ms │         9.63 / 10.09 ±0.33 / 10.49 ms │ +1.08x faster │
│ QQuery 74 │     156.84 / 159.50 ±3.11 / 165.55 ms │     150.79 / 153.80 ±1.99 / 157.01 ms │     no change │
│ QQuery 75 │     137.86 / 139.84 ±1.36 / 141.49 ms │     138.42 / 140.80 ±2.77 / 145.97 ms │     no change │
│ QQuery 76 │        33.89 / 34.35 ±0.42 / 34.99 ms │        33.33 / 34.18 ±0.61 / 35.10 ms │     no change │
│ QQuery 77 │        58.42 / 61.76 ±4.37 / 70.29 ms │        59.16 / 59.99 ±0.78 / 61.34 ms │     no change │
│ QQuery 78 │     159.62 / 165.66 ±4.64 / 171.33 ms │     159.97 / 162.81 ±2.45 / 165.82 ms │     no change │
│ QQuery 79 │        65.27 / 68.66 ±4.11 / 76.75 ms │        65.51 / 66.41 ±1.21 / 68.75 ms │     no change │
│ QQuery 80 │        94.60 / 95.83 ±0.98 / 97.25 ms │       93.41 / 96.57 ±3.19 / 102.60 ms │     no change │
│ QQuery 81 │        24.69 / 25.29 ±0.33 / 25.64 ms │        25.34 / 25.84 ±0.43 / 26.62 ms │     no change │
│ QQuery 82 │        15.97 / 16.28 ±0.25 / 16.60 ms │        15.96 / 16.23 ±0.22 / 16.53 ms │     no change │
│ QQuery 83 │        32.90 / 35.62 ±4.90 / 45.39 ms │        32.68 / 33.78 ±1.30 / 36.33 ms │ +1.05x faster │
│ QQuery 84 │        28.91 / 29.59 ±0.72 / 30.71 ms │        29.07 / 29.31 ±0.12 / 29.44 ms │     no change │
│ QQuery 85 │     101.11 / 102.69 ±0.83 / 103.40 ms │     100.52 / 103.09 ±2.81 / 108.38 ms │     no change │
│ QQuery 86 │        25.44 / 25.49 ±0.04 / 25.56 ms │        24.72 / 25.40 ±0.44 / 26.03 ms │     no change │
│ QQuery 87 │        60.67 / 61.44 ±0.66 / 62.51 ms │        61.07 / 62.11 ±0.95 / 63.91 ms │     no change │
│ QQuery 88 │        59.40 / 60.03 ±0.46 / 60.74 ms │        59.30 / 60.62 ±1.80 / 64.14 ms │     no change │
│ QQuery 89 │        34.74 / 35.17 ±0.38 / 35.83 ms │        34.81 / 35.32 ±0.43 / 35.86 ms │     no change │
│ QQuery 90 │        15.93 / 16.23 ±0.21 / 16.57 ms │        15.93 / 16.19 ±0.24 / 16.60 ms │     no change │
│ QQuery 91 │        43.74 / 44.09 ±0.30 / 44.57 ms │        43.13 / 43.95 ±0.52 / 44.71 ms │     no change │
│ QQuery 92 │        29.03 / 31.97 ±5.17 / 42.30 ms │        28.61 / 29.09 ±0.47 / 29.96 ms │ +1.10x faster │
│ QQuery 93 │        48.67 / 49.66 ±0.82 / 50.88 ms │        48.34 / 49.68 ±0.94 / 51.20 ms │     no change │
│ QQuery 94 │        38.47 / 39.18 ±0.79 / 40.70 ms │        37.39 / 38.64 ±1.55 / 41.55 ms │     no change │
│ QQuery 95 │        79.66 / 80.20 ±0.43 / 80.93 ms │        78.63 / 79.10 ±0.39 / 79.76 ms │     no change │
│ QQuery 96 │        23.60 / 24.27 ±0.89 / 25.99 ms │        23.31 / 23.75 ±0.76 / 25.26 ms │     no change │
│ QQuery 97 │        50.55 / 51.97 ±1.35 / 54.00 ms │        50.35 / 51.37 ±0.77 / 52.29 ms │     no change │
│ QQuery 98 │        42.31 / 43.26 ±0.77 / 44.34 ms │        42.35 / 43.73 ±1.04 / 45.52 ms │     no change │
│ QQuery 99 │        65.25 / 65.60 ±0.38 / 66.26 ms │        65.13 / 65.34 ±0.13 / 65.49 ms │     no change │
└───────────┴───────────────────────────────────────┴───────────────────────────────────────┴───────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━┓
┃ Benchmark Summary                                 ┃           ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━┩
│ Total Time (HEAD)                                 │ 9101.28ms │
│ Total Time (codex_25936-numeric-distinct-count)   │ 9015.25ms │
│ Average Time (HEAD)                               │   91.93ms │
│ Average Time (codex_25936-numeric-distinct-count) │   91.06ms │
│ Queries Faster                                    │         8 │
│ Queries Slower                                    │         2 │
│ Queries with No Change                            │        89 │
│ Queries with Failure                              │         0 │
└───────────────────────────────────────────────────┴───────────┘

Resource Usage

tpcds — base (merge-base)

Metric Value
Wall time 50.0s
Peak memory 2.1 GiB
Avg memory 1.4 GiB
CPU user 197.3s
CPU sys 5.8s
Peak spill 0 B

tpcds — branch

Metric Value
Wall time 50.0s
Peak memory 2.0 GiB
Avg memory 1.3 GiB
CPU user 195.6s
CPU sys 5.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 codex/25936-numeric-distinct-count (3ae5962) to 416002a (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 codex_25936-numeric-distinct-count
--------------------
Benchmark clickbench_partitioned.json
--------------------
┏━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┓
┃ Query     ┃       HEAD ┃ codex_25936-numeric-distinct-count ┃       Change ┃
┡━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━┩
│ QQuery 0  │    1.24 ms │                            1.24 ms │    no change │
│ QQuery 1  │   11.71 ms │                           11.60 ms │    no change │
│ QQuery 2  │   36.52 ms │                           36.37 ms │    no change │
│ QQuery 3  │   31.34 ms │                           31.27 ms │    no change │
│ QQuery 4  │  236.22 ms │                          231.22 ms │    no change │
│ QQuery 5  │  268.86 ms │                          273.57 ms │    no change │
│ QQuery 6  │    1.29 ms │                            1.30 ms │    no change │
│ QQuery 7  │   12.55 ms │                           12.62 ms │    no change │
│ QQuery 8  │  325.64 ms │                          372.06 ms │ 1.14x slower │
│ QQuery 9  │  451.07 ms │                          463.83 ms │    no change │
│ QQuery 10 │   63.36 ms │                           91.77 ms │ 1.45x slower │
│ QQuery 11 │   74.08 ms │                           99.50 ms │ 1.34x slower │
│ QQuery 12 │  259.37 ms │                          258.50 ms │    no change │
│ QQuery 13 │  354.44 ms │                          376.76 ms │ 1.06x slower │
│ QQuery 14 │  276.81 ms │                          276.71 ms │    no change │
│ QQuery 15 │  281.24 ms │                          282.25 ms │    no change │
│ QQuery 16 │  611.70 ms │                          617.75 ms │    no change │
│ QQuery 17 │  618.89 ms │                          621.16 ms │    no change │
│ QQuery 18 │ 1260.74 ms │                         1257.39 ms │    no change │
│ QQuery 19 │   27.58 ms │                           27.51 ms │    no change │
│ QQuery 20 │  518.56 ms │                          520.46 ms │    no change │
│ QQuery 21 │  512.83 ms │                          520.66 ms │    no change │
│ QQuery 22 │ 1003.64 ms │                         1052.40 ms │    no change │
│ QQuery 23 │ 3086.85 ms │                         3170.50 ms │    no change │
│ QQuery 24 │   40.19 ms │                           42.03 ms │    no change │
│ QQuery 25 │  103.82 ms │                          103.74 ms │    no change │
│ QQuery 26 │   40.59 ms │                           40.74 ms │    no change │
│ QQuery 27 │  510.50 ms │                          520.58 ms │    no change │
│ QQuery 28 │ 2864.86 ms │                         2819.40 ms │    no change │
│ QQuery 29 │   38.95 ms │                           39.40 ms │    no change │
│ QQuery 30 │  302.67 ms │                          300.96 ms │    no change │
│ QQuery 31 │  272.54 ms │                          267.60 ms │    no change │
│ QQuery 32 │ 1070.57 ms │                         1073.93 ms │    no change │
│ QQuery 33 │ 1544.84 ms │                         1537.08 ms │    no change │
│ QQuery 34 │ 1574.42 ms │                         1560.73 ms │    no change │
│ QQuery 35 │  295.67 ms │                          294.98 ms │    no change │
│ QQuery 36 │   68.06 ms │                           78.92 ms │ 1.16x slower │
│ QQuery 37 │   35.97 ms │                           34.37 ms │    no change │
│ QQuery 38 │   41.69 ms │                           40.62 ms │    no change │
│ QQuery 39 │  140.14 ms │                          154.10 ms │ 1.10x slower │
│ QQuery 40 │   13.78 ms │                           13.90 ms │    no change │
│ QQuery 41 │   12.97 ms │                           13.06 ms │    no change │
│ QQuery 42 │   12.79 ms │                           12.69 ms │    no change │
└───────────┴────────────┴────────────────────────────────────┴──────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┓
┃ Benchmark Summary                                 ┃            ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━┩
│ Total Time (HEAD)                                 │ 19311.56ms │
│ Total Time (codex_25936-numeric-distinct-count)   │ 19557.20ms │
│ Average Time (HEAD)                               │   449.11ms │
│ Average Time (codex_25936-numeric-distinct-count) │   454.82ms │
│ Queries Faster                                    │          0 │
│ Queries Slower                                    │          6 │
│ Queries with No Change                            │         37 │
│ Queries with Failure                              │          0 │
└───────────────────────────────────────────────────┴────────────┘

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

Comparing HEAD and codex_25936-numeric-distinct-count
--------------------
Benchmark clickbench_partitioned.json
--------------------
┏━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Query     ┃                                   HEAD ┃     codex_25936-numeric-distinct-count ┃        Change ┃
┡━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ QQuery 0  │           1.24 / 3.96 ±5.36 / 14.68 ms │           1.24 / 3.96 ±5.39 / 14.74 ms │     no change │
│ QQuery 1  │         11.71 / 11.82 ±0.09 / 11.96 ms │         11.60 / 11.72 ±0.14 / 12.00 ms │     no change │
│ QQuery 2  │         36.52 / 36.70 ±0.18 / 37.00 ms │         36.37 / 37.08 ±0.97 / 39.01 ms │     no change │
│ QQuery 3  │         31.34 / 32.52 ±1.19 / 34.21 ms │         31.27 / 31.44 ±0.15 / 31.66 ms │     no change │
│ QQuery 4  │      236.22 / 240.23 ±3.79 / 246.47 ms │      231.22 / 236.30 ±2.67 / 239.00 ms │     no change │
│ QQuery 5  │      268.86 / 271.79 ±1.65 / 273.87 ms │      273.57 / 276.63 ±2.56 / 279.41 ms │     no change │
│ QQuery 6  │            1.29 / 1.60 ±0.49 / 2.58 ms │            1.30 / 1.46 ±0.24 / 1.92 ms │ +1.09x faster │
│ QQuery 7  │         12.55 / 12.86 ±0.17 / 13.06 ms │         12.62 / 12.87 ±0.13 / 12.97 ms │     no change │
│ QQuery 8  │      325.64 / 330.47 ±2.99 / 334.82 ms │      372.06 / 384.26 ±6.34 / 389.79 ms │  1.16x slower │
│ QQuery 9  │      451.07 / 459.72 ±8.22 / 472.80 ms │      463.83 / 469.35 ±4.38 / 477.28 ms │     no change │
│ QQuery 10 │         63.36 / 64.10 ±0.76 / 65.08 ms │       91.77 / 100.51 ±8.77 / 116.63 ms │  1.57x slower │
│ QQuery 11 │         74.08 / 74.91 ±0.92 / 76.62 ms │       99.50 / 106.35 ±7.89 / 121.59 ms │  1.42x slower │
│ QQuery 12 │      259.37 / 262.90 ±3.33 / 269.19 ms │      258.50 / 268.09 ±8.55 / 281.71 ms │     no change │
│ QQuery 13 │      354.44 / 364.54 ±6.24 / 372.09 ms │     376.76 / 396.38 ±28.17 / 450.47 ms │  1.09x slower │
│ QQuery 14 │      276.81 / 282.98 ±4.46 / 289.02 ms │      276.71 / 281.23 ±3.12 / 285.10 ms │     no change │
│ QQuery 15 │      281.24 / 284.99 ±2.94 / 288.64 ms │     282.25 / 293.63 ±10.03 / 310.19 ms │     no change │
│ QQuery 16 │      611.70 / 622.63 ±6.63 / 631.49 ms │      617.75 / 623.70 ±4.77 / 630.12 ms │     no change │
│ QQuery 17 │      618.89 / 633.63 ±8.96 / 645.27 ms │      621.16 / 633.21 ±7.10 / 643.12 ms │     no change │
│ QQuery 18 │  1260.74 / 1279.07 ±11.80 / 1292.83 ms │  1257.39 / 1278.49 ±14.69 / 1296.44 ms │     no change │
│ QQuery 19 │         27.58 / 28.22 ±0.86 / 29.79 ms │         27.51 / 33.64 ±8.64 / 49.75 ms │  1.19x slower │
│ QQuery 20 │     518.56 / 528.60 ±10.53 / 543.74 ms │      520.46 / 526.00 ±6.09 / 536.55 ms │     no change │
│ QQuery 21 │      512.83 / 520.65 ±9.43 / 538.49 ms │     520.66 / 532.92 ±12.62 / 555.47 ms │     no change │
│ QQuery 22 │   1003.64 / 1012.37 ±9.33 / 1025.17 ms │  1052.40 / 1082.78 ±28.54 / 1133.02 ms │  1.07x slower │
│ QQuery 23 │ 3086.85 / 3256.84 ±124.21 / 3419.73 ms │ 3170.50 / 3345.33 ±270.20 / 3883.61 ms │     no change │
│ QQuery 24 │       40.19 / 68.02 ±53.22 / 174.45 ms │       42.03 / 55.88 ±26.22 / 108.31 ms │ +1.22x faster │
│ QQuery 25 │    103.82 / 171.64 ±130.44 / 432.50 ms │      103.74 / 104.90 ±1.28 / 107.32 ms │ +1.64x faster │
│ QQuery 26 │         40.59 / 40.91 ±0.22 / 41.22 ms │       40.74 / 56.89 ±30.74 / 118.35 ms │  1.39x slower │
│ QQuery 27 │      510.50 / 518.49 ±6.63 / 527.23 ms │      520.58 / 526.00 ±4.99 / 534.96 ms │     no change │
│ QQuery 28 │  2864.86 / 2915.86 ±60.21 / 3025.75 ms │  2819.40 / 2847.01 ±17.10 / 2866.08 ms │     no change │
│ QQuery 29 │         38.95 / 39.18 ±0.18 / 39.51 ms │        39.40 / 54.57 ±17.84 / 78.15 ms │  1.39x slower │
│ QQuery 30 │      302.67 / 316.14 ±8.31 / 325.94 ms │      300.96 / 310.30 ±8.00 / 323.59 ms │     no change │
│ QQuery 31 │      272.54 / 282.96 ±6.45 / 289.62 ms │     267.60 / 292.80 ±16.67 / 319.33 ms │     no change │
│ QQuery 32 │ 1070.57 / 1178.91 ±147.04 / 1467.73 ms │  1073.93 / 1133.42 ±65.20 / 1247.75 ms │     no change │
│ QQuery 33 │  1544.84 / 1581.57 ±25.65 / 1616.23 ms │  1537.08 / 1613.72 ±39.66 / 1644.64 ms │     no change │
│ QQuery 34 │  1574.42 / 1597.62 ±21.76 / 1631.37 ms │  1560.73 / 1604.89 ±32.45 / 1646.62 ms │     no change │
│ QQuery 35 │     295.67 / 344.86 ±69.62 / 477.92 ms │     294.98 / 346.47 ±84.41 / 514.68 ms │     no change │
│ QQuery 36 │         68.06 / 73.75 ±4.22 / 81.19 ms │         78.92 / 83.65 ±5.37 / 92.98 ms │  1.13x slower │
│ QQuery 37 │         35.97 / 39.40 ±4.05 / 45.65 ms │         34.37 / 38.22 ±6.34 / 50.80 ms │     no change │
│ QQuery 38 │         41.69 / 48.79 ±8.13 / 64.72 ms │         40.62 / 46.21 ±4.08 / 51.44 ms │ +1.06x faster │
│ QQuery 39 │     140.14 / 161.08 ±12.79 / 176.09 ms │      154.10 / 159.04 ±5.45 / 167.13 ms │     no change │
│ QQuery 40 │         13.78 / 14.32 ±0.45 / 14.96 ms │         13.90 / 16.09 ±3.13 / 22.25 ms │  1.12x slower │
│ QQuery 41 │         12.97 / 13.56 ±0.32 / 13.94 ms │         13.06 / 15.62 ±4.16 / 23.91 ms │  1.15x slower │
│ QQuery 42 │        12.79 / 21.25 ±12.38 / 44.83 ms │         12.69 / 12.98 ±0.33 / 13.62 ms │ +1.64x faster │
└───────────┴────────────────────────────────────────┴────────────────────────────────────────┴───────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┓
┃ Benchmark Summary                                 ┃            ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━┩
│ Total Time (HEAD)                                 │ 20046.39ms │
│ Total Time (codex_25936-numeric-distinct-count)   │ 20286.00ms │
│ Average Time (HEAD)                               │   466.20ms │
│ Average Time (codex_25936-numeric-distinct-count) │   471.77ms │
│ Queries Faster                                    │          5 │
│ Queries Slower                                    │         11 │
│ Queries with No Change                            │         27 │
│ Queries with Failure                              │          0 │
└───────────────────────────────────────────────────┴────────────┘

Resource Usage

clickbench_partitioned — base (merge-base)

Metric Value
Wall time 105.0s
Peak memory 18.0 GiB
Avg memory 5.8 GiB
CPU user 989.5s
CPU sys 99.0s
Peak spill 0 B

clickbench_partitioned — branch

Metric Value
Wall time 105.0s
Peak memory 17.9 GiB
Avg memory 6.1 GiB
CPU user 981.4s
CPU sys 99.7s
Peak spill 0 B

File an issue against this benchmark runner

@QinXi-ai QinXi-ai changed the title fix: keep grouped integer DISTINCT counts on the native accumulator path perf: retain native grouped integer DISTINCT counts with one target partition Oct 7, 2026
@QinXi-ai

QinXi-ai commented Nov 2, 2026

Copy link
Copy Markdown
Contributor Author

Synced with main and fixed the spill-test conflict. The optimization still only applies with target_partitions = 1; parallel queries keep the existing rewrite. Local tests and lint pass.

@Dandandan, could you rerun the benchmarks when you have a chance? The earlier run was on the version that also changed multi-partition plans.

I also tried to rerun Rust CI on the fork, but GitHub rejects it with "Actions has been disabled for this repository", even though Actions is enabled in the repo settings.

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

Optional cleanup: in single_distinct_to_groupby.rs around line 70, the rule's doc comment still reads as if the rewrite always applies. A sentence on when grouped DISTINCT stays native would help the next reader.

// keeping DISTINCT instead repartitions lists of values by group and merges
// them in the final accumulator. That can concentrate work on a few groups.
// Native accumulator support alone does not establish that this is cheaper.
if use_native_grouped_distinct

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.

@QinXi-ai Thanks for working on this. With spilling on, this turns queries that finish under a memory limit into ResourcesExhausted: the rewrite dedupes through sorted (g, x) spill runs, but the native accumulator has to hold every distinct value of the largest group in memory. ClickBench Q8 at one partition finishes at -m 16M on main and fails at -m 128M here (it passes at 256M). The equal-memory table in #25936 used -d 0, where neither plan can spill.

SET datafusion.execution.target_partitions = 1;
SET datafusion.execution.batch_size = 128;
SET datafusion.runtime.memory_limit = '1M';
-- main: 2, 100000. This PR: Resources exhausted
SELECT count(*), sum(d) FROM (
  SELECT v % 2 AS k, count(DISTINCT v) AS d
  FROM generate_series(1, 100000) AS t(v)
  GROUP BY v % 2
);

The rule can't see the memory pool, so it can't choose per query. Could you make the native plan opt-in so the rewrite stays the default? #26000 adds a very similar flag to this rule, so it's worth settling on one.

!group_expr.is_empty()
    && config.options().execution.target_partitions == 1
    && config.options().optimizer.single_distinct_prefer_native

Please add the query above to aggregate_memory_spill.slt as the flag-off test, plus an EXPLAIN with the flag on showing the native plan. If a maintainer would rather keep it on by default, it needs an upgrade guide note, and the "Query results ... are unchanged" line in the description needs correcting.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks, I missed this because the spill test only had one distinct value per group. I've made the native path opt-in with single_distinct_prefer_native, defaulting to false. Your 1 MiB reproducer now passes with the default; the test also checks the native EXPLAIN and memory error with the flag on. I used your prefer_native name since native can use more memory too. Agreed on sharing one setting with #26000.

CAST((value * 48271) % 999983 AS VARCHAR) AS string_x,
CAST((value * 48271) % 999983 AS DOUBLE) AS float_x,
CASE WHEN value % 100 < 90 THEN 0 ELSE value % 8 END AS skew_g,
CAST(CASE WHEN value % 100 < 90 THEN 0 ELSE value % 8 END AS VARCHAR) AS string_g

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 suite doesn't include the shape where the native plan loses: many groups with duplicate rows. With 1M groups and four rows per group, I measured it about 1.4x slower than main (about 130 ms vs 93 ms median, on a busy laptop), because every row probes both the group table and seen, while the rewrite's outer aggregate only sees each pair once. The rule has no statistics to avoid this, so could you add a q10 over these columns and state this worst case in the description?

Suggested change
CAST(CASE WHEN value % 100 < 90 THEN 0 ELSE value % 8 END AS VARCHAR) AS string_g
CAST(CASE WHEN value % 100 < 90 THEN 0 ELSE value % 8 END AS VARCHAR) AS string_g,
value % 1000000 AS many_g,
value % 2 AS dup_x

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added Q10 with those columns and reproduced the slowdown: at 4M rows and one target partition, I got 398.12 ms with native enabled vs 284.87 ms with it off, about 40% slower (15 retained samples each). I've put this alongside the original workload's improvement in the description and added off/on commands to the suite README.

input.schema(),
count_rollup.as_ref(),
!group_expr.is_empty()
&& config.options().execution.target_partitions == 1,

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.

target_partitions == 1 doesn't guarantee one input partition: a UNION ALL or a table created at higher parallelism still plans Partial, Coalesce, Final, which is the list-merge path this PR avoids for parallel plans. A 4-partition table with a hot group ran about 1.3x slower than main in my runs, since Partial dedupes first and Final rebuilds the set. Could you add this test before the switch to four partitions, so that path is covered, and mention the case in the comment above use_native_grouped_distinct?

query II rowsort
SELECT g, count(DISTINCT x)
FROM (SELECT g, x FROM numeric_counts UNION ALL SELECT g, x FROM numeric_counts)
GROUP BY g;
----
1 2
2 0
3 1

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

You're right, one target partition can still merge several input partitions. Added your UNION ALL query and a table built at four partitions then queried at one. Both have result checks and physical-plan snapshots showing Partial/Coalesce/Final. The comment now calls out these cases.

Ok(true)
}

fn all_have_groups_accumulators(

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.

Optional cleanup: this repeats the loop in rewrite_pays_for_count, and the two only differ in which answer they look for. One helper covers both:

-fn all_have_groups_accumulators(
+/// Each distinct aggregate's answer to whether a specialized `GroupsAccumulator`
+/// exists for its argument types.
+fn distinct_groups_support(
     distinct_aggs: &[(&Arc<AggregateUDF>, &[Expr])],
     input_schema: &DFSchema,
-) -> Result<bool> {
-    for (func, args) in distinct_aggs {
-        let arg_types = args
-            .iter()
-            .map(|arg| arg.get_type(input_schema))
-            .collect::<Result<Vec<_>>>()?;
-        // An unknown answer must preserve the existing rewrite.
-        if func.groups_accumulator_supported_for_types(&arg_types, true) != Some(true) {
-            return Ok(false);
-        }
-    }
-    Ok(true)
+) -> Result<Vec<Option<bool>>> {
+    distinct_aggs
+        .iter()
+        .map(|(func, args)| {
+            let arg_types = args
+                .iter()
+                .map(|arg| arg.get_type(input_schema))
+                .collect::<Result<Vec<_>>>()?;
+            Ok(func.groups_accumulator_supported_for_types(&arg_types, true))
+        })
+        .collect()
 }

The call here becomes distinct_groups_support(&distinct_aggs, input_schema)?.iter().all(|support| *support == Some(true)), and rewrite_pays_for_count becomes Ok(distinct_groups_support(distinct_aggs, input_schema)?.contains(&Some(false))).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done, both checks now share the type lookup through distinct_groups_support. I also added the opt-in exception to the rule's doc comment.

Preserve the spill-capable rewrite by default and document the native
plan's memory and duplicate-heavy workload tradeoffs. Cover low-memory
execution and multiple input partitions, and add the million-group
duplicate benchmark.
@github-actions github-actions Bot added documentation Improvements or additions to documentation common Related to common crate labels Nov 7, 2026
@QinXi-ai QinXi-ai changed the title perf: retain native grouped integer DISTINCT counts with one target partition perf: add opt-in native grouped integer DISTINCT counts Nov 7, 2026
Regenerate configuration documentation after merging main 4bf32cb.

Generated-by: OpenAI Codex
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.

Grouped count(DISTINCT x) on numbers takes a slower path

5 participants