Skip to content

feat: sort file groups by statistics during sort pushdown (Sort pushdown phase 2)#21182

Merged
adriangb merged 17 commits intoapache:mainfrom
zhuqi-lucas:feat/sort-file-groups-by-statistics
Apr 6, 2026
Merged

feat: sort file groups by statistics during sort pushdown (Sort pushdown phase 2)#21182
adriangb merged 17 commits intoapache:mainfrom
zhuqi-lucas:feat/sort-file-groups-by-statistics

Conversation

@zhuqi-lucas
Copy link
Copy Markdown
Contributor

@zhuqi-lucas zhuqi-lucas commented Mar 26, 2026

Which issue does this PR close?

Rationale for this change

When a partition (file group) contains multiple files in wrong order, validated_output_ordering() strips the ordering and EnforceSorting inserts an unnecessary SortExec — even though the files are non-overlapping and internally sorted.

This PR fixes it by sorting files within each group by min/max statistics during sort pushdown. After sorting, the file order matches the sort key order, the ordering becomes valid, and SortExec can be eliminated. This works for both single-partition and multi-partition plans with multi-file groups.

What changes are included in this PR?

Core optimization

Files in wrong order within a partition:     After statistics-based sorting:
  [a_high(400k+), b_mid(200k), c_low(1)]     [c_low(1), b_mid(200k), a_high(400k+)]
  → ordering stripped                          → ordering valid, non-overlapping
  → SortExec stays                             → SortExec eliminated

When PushdownSort finds a SortExec above a file-based DataSourceExec:

  1. FileSource returns Exact (natural ordering satisfies request):

    • Sort files within each group by statistics, verify non-overlapping
    • SortExec removed, fetch (LIMIT) pushed to DataSourceExec
  2. FileSource returns Unsupported (ordering stripped due to wrong file order):

    • Sort files within each group by statistics
    • Re-check: if files are now non-overlapping and ordering is valid → upgrade to Exact
    • SortExec eliminated + fetch pushed down
  3. FileSource returns Inexact (reverse scan):

    • SortExec kept, scan optimized with reverse_row_groups

Files Changed

File Change
datasource-parquet/src/source.rs ParquetSource returns Exact when natural ordering satisfies request
datasource/src/file_scan_config.rs Statistics-based file sorting, non-overlapping re-check, Unsupported→Exact upgrade
physical-optimizer/src/pushdown_sort.rs Preserve fetch (LIMIT) when eliminating SortExec, module doc update
core/tests/physical_optimizer/pushdown_sort.rs Updated prefix match test
sqllogictest/test_files/sort_pushdown.slt Updated existing tests + 5 new test groups (A-E)

Benchmark Results

Local release build, --partitions 1, 3 non-overlapping files with reversed naming (6M rows):

Query Description Main (ms) PR (ms) Speedup
Q1 ORDER BY ASC (full scan) 259 122 2.1x faster
Q2 ORDER BY ASC LIMIT 100 80 3 27x faster
Q3 SELECT * ORDER BY ASC 700 313 2.2x faster
Q4 SELECT * LIMIT 100 342 7 49x faster

LIMIT queries benefit most because sort elimination + limit pushdown means only the first ~100 rows are read.

Tests

  • 13 new unit tests covering all sort pushdown paths
  • 5 new SLT integration test groups (sort elimination, overlapping files, LIMIT, multi-partition, inferred ordering)
  • All existing tests pass with no regressions

Test plan

  • cargo test -p datafusion-datasource — all tests pass
  • cargo test -p datafusion-datasource-parquet — all tests pass
  • cargo test -p datafusion-physical-optimizer — all tests pass
  • cargo test -p datafusion --test core_integration — all tests pass
  • SLT sort/order/topk/window/union/joins tests pass (no regressions)
  • cargo clippy — 0 warnings

🤖 Generated with Claude Code

Copilot AI review requested due to automatic review settings March 26, 2026 15:54
@zhuqi-lucas
Copy link
Copy Markdown
Contributor Author

cc @alamb @adriangb — this implements the sort pushdown phase 2 from #17348. Would appreciate your review when you get a chance.

@zhuqi-lucas zhuqi-lucas changed the title feat: sort file groups by statistics during sort pushdown feat: sort file groups by statistics during sort pushdown (Sort pushdown phase 2) Mar 26, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Implements statistics-driven file group ordering as part of sort pushdown, enabling sort elimination when within-file ordering matches and files are non-overlapping, plus a best-effort stats-based reorder fallback when exact pushdown isn’t possible.

Changes:

  • Add file-group reordering by min/max statistics (and non-overlap validation) to enable SortExec elimination for exactly ordered, non-overlapping files.
  • Extend Parquet sort pushdown to return Exact when Parquet ordering metadata satisfies the requested ordering.
  • Add/adjust SLT + Rust tests and a new benchmark to validate and measure the optimization.

Reviewed changes

Copilot reviewed 8 out of 9 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
datafusion/sqllogictest/test_files/sort_pushdown.slt Adds SLT coverage for stats reorder, sort elimination, LIMIT behavior, multi-partition behavior, and inferred ordering from Parquet metadata.
datafusion/physical-optimizer/src/pushdown_sort.rs Updates module docs to reflect new capabilities (Exact elimination + stats-based ordering).
datafusion/datasource/src/file_scan_config.rs Implements core stats-based reordering, non-overlap validation, “exact” preservation logic, and cross-group redistribution. Adds unit tests.
datafusion/datasource-parquet/src/source.rs Returns Exact when Parquet natural ordering satisfies the requested sort.
datafusion/core/tests/physical_optimizer/pushdown_sort.rs Updates a prefix-match test to reflect Exact pushdown / sort elimination behavior.
benchmarks/src/sort_pushdown.rs Adds a benchmark to measure sort elimination and LIMIT benefits on sorted, non-overlapping parquet files.
benchmarks/src/lib.rs Registers the new sort_pushdown benchmark module.
benchmarks/src/bin/dfbench.rs Exposes sort-pushdown as a new dfbench subcommand.
benchmarks/bench.sh Adds bench.sh targets to run the new sort pushdown benchmarks.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@github-actions github-actions bot added optimizer Optimizer rules core Core DataFusion crate sqllogictest SQL Logic Tests (.slt) datasource Changes to the datasource crate labels Mar 26, 2026
@adriangb
Copy link
Copy Markdown
Contributor

Very exciting! I hope I have wifi on the plane later today so I can review.

Copy link
Copy Markdown
Contributor

@adriangb adriangb left a comment

Choose a reason for hiding this comment

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

Just some comment for now. My flight ended up being a 4 hour delay on the tarmac debacle.


use datafusion_benchmarks::{
cancellation, clickbench, h2o, hj, imdb, nlj, smj, sort_tpch, tpcds, tpch,
cancellation, clickbench, h2o, hj, imdb, nlj, smj, sort_pushdown, sort_tpch, tpcds,
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.

Adding sort_pushdown. To keep the PR smaller and so we can run comparison benchmarks, could you split the benchmarks out into their own PR?

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 for the review! Good idea — will split the benchmarks into a follow-up PR to keep this one focused on the core optimization.

inner: Arc::new(new_source) as Arc<dyn FileSource>,
})

// TODO Phase 2: Add support for other optimizations:
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.

I do think there's one more trick we could have up our sleeves: instead of only reversing row group orders we could pass the desired sort order into the opener and have it re-sort the row groups based on stats to try to match the scan's desired ordering. This might be especially effective once we have morselized scans since we could terminate after a single row group for TopK queries.

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.

Great idea! Row-group-level statistics reordering would be a natural extension of our file-level reordering but at finer granularity. Especially powerful with morselized scans where TopK could terminate after a single row group. Will track as a follow-up.

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.

If you're able to open a followup issue and link it to the PR and code that would be great!

Copy link
Copy Markdown
Contributor Author

@zhuqi-lucas zhuqi-lucas Apr 2, 2026

Choose a reason for hiding this comment

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

@adriangb Created follow-up issue: #21317

Great idea! Row-group-level statistics reordering would be a natural extension of our file-level reordering but at finer granularity. Especially powerful with morselized scans where TopK could terminate after a single row group.

///
/// # Sort Pushdown Architecture
///
/// ```text
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.

This diagram is amazing, thank you so much for the detailed docs!

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.

Thank you for taking the time to review! Really appreciate it.

/// │
/// └─► try_sort_file_groups_by_statistics()
/// (best-effort: reorder files by min/max stats)
/// └─► Inexact if reordered, Unsupported if already in order
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.

Unsupported if already in order

I didn't understand this part

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.

Good catch — let me clarify. When FileSource returns Unsupported, we fall back to try_sort_file_groups_by_statistics() which reorders files by min/max stats. But if the files are already in the correct order (any_reordered = false), we return Unsupported rather than Inexact — because we did not actually change anything. Returning Inexact would make the optimizer think we optimized the plan, but it is identical to the original. Will improve the wording in the comment.

Comment on lines +1418 to +1427
// When there are multiple groups, redistribute files using consecutive
// assignment so that each group remains non-overlapping AND groups are
// ordered relative to each other. This enables:
// - No SortExec per partition (files in each group are sorted & non-overlapping)
// - SPM cheaply merges ordered streams (O(n) merge)
// - Parallel I/O across partitions
//
// Before (bin-packing may interleave):
// Group 0: [file_01(1-10), file_03(21-30)] ← gap, interleaved with group 1
// Group 1: [file_02(11-20), file_04(31-40)]
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.

Are there scenarios where ending up with lopsided partitions negates the benefits?

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.

In practice the impact is minimal: file count is typically much larger than partition count, so the imbalance is at most 1 extra file (e.g. 51 vs 50 files). Even with some imbalance, parallel I/O across partitions still beats single-partition sequential reads. For LIMIT queries it matters even less since the first partition hits the limit and stops early regardless of size.

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.

After further analysis, I am considering removing the redistribution logic entirely. The three benefits listed in the comment are not actually unique to redistribution:

  1. No SortExec per partition — true regardless of redistribution, as long as files within each group are non-overlapping
  2. SPM cheaply merges ordered streams — SPM is O(n) merge whether groups are interleaved or consecutive
  3. Parallel I/O across partitions — actually better with interleaved groups, since SPM alternates pulling from both partitions, keeping both I/O streams active

The only real difference is that consecutive assignment makes each partition's file reads more sequential (fewer open/close alternations). But interleaved groups give better I/O parallelism because both partitions are actively scanning simultaneously.

Given the marginal benefit vs added complexity (new function + tests), I think we should remove redistribute_files_across_groups_by_statistics and just keep the core optimization: per-partition sort elimination via statistics-based non-overlapping detection.

What do you think?

@adriangb
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-c4141601401-576-882hz 6.12.55+ #1 SMP Sun Feb 1 08:59:41 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 feat/sort-file-groups-by-statistics (a79cbdf) to 7cbc6b4 (merge-base) diff using: 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-c4141601401-577-k58hp 6.12.55+ #1 SMP Sun Feb 1 08:59:41 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 feat/sort-file-groups-by-statistics (a79cbdf) to 7cbc6b4 (merge-base) diff using: 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-c4141601401-578-ndf9j 6.12.55+ #1 SMP Sun Feb 1 08:59:41 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 feat/sort-file-groups-by-statistics (a79cbdf) to 7cbc6b4 (merge-base) diff using: 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)

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 feat_sort-file-groups-by-statistics
--------------------
Benchmark tpch_sf1.json
--------------------
┏━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━┓
┃ Query     ┃                           HEAD ┃ feat_sort-file-groups-by-statistics ┃    Change ┃
┡━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━┩
│ QQuery 1  │ 45.25 / 45.93 ±0.93 / 47.76 ms │      45.34 / 45.75 ±0.65 / 47.05 ms │ no change │
│ QQuery 2  │ 21.14 / 21.63 ±0.62 / 22.83 ms │      21.14 / 21.55 ±0.47 / 22.45 ms │ no change │
│ QQuery 3  │ 31.68 / 31.92 ±0.13 / 32.04 ms │      31.99 / 32.54 ±0.81 / 34.09 ms │ no change │
│ QQuery 4  │ 20.32 / 21.44 ±0.96 / 22.85 ms │      20.42 / 21.08 ±0.53 / 21.99 ms │ no change │
│ QQuery 5  │ 47.55 / 49.00 ±2.12 / 53.20 ms │      50.20 / 51.12 ±0.47 / 51.54 ms │ no change │
│ QQuery 6  │ 17.10 / 17.22 ±0.14 / 17.48 ms │      17.15 / 17.34 ±0.17 / 17.63 ms │ no change │
│ QQuery 7  │ 54.14 / 55.47 ±1.34 / 57.58 ms │      53.89 / 54.61 ±0.45 / 55.21 ms │ no change │
│ QQuery 8  │ 48.09 / 48.50 ±0.25 / 48.85 ms │      48.06 / 48.59 ±0.28 / 48.85 ms │ no change │
│ QQuery 9  │ 54.15 / 55.30 ±1.17 / 56.82 ms │      53.57 / 55.15 ±2.09 / 59.28 ms │ no change │
│ QQuery 10 │ 71.19 / 72.23 ±0.91 / 73.62 ms │      71.46 / 72.22 ±0.72 / 73.52 ms │ no change │
│ QQuery 11 │ 14.01 / 14.51 ±0.83 / 16.16 ms │      13.98 / 14.23 ±0.17 / 14.42 ms │ no change │
│ QQuery 12 │ 27.75 / 28.20 ±0.70 / 29.58 ms │      27.86 / 28.87 ±1.35 / 31.54 ms │ no change │
│ QQuery 13 │ 37.80 / 38.71 ±0.58 / 39.46 ms │      38.74 / 39.39 ±0.43 / 40.03 ms │ no change │
│ QQuery 14 │ 28.58 / 28.91 ±0.33 / 29.51 ms │      28.49 / 29.07 ±0.56 / 30.14 ms │ no change │
│ QQuery 15 │ 33.29 / 34.47 ±1.06 / 36.28 ms │      33.69 / 34.42 ±0.54 / 34.97 ms │ no change │
│ QQuery 16 │ 15.73 / 16.10 ±0.31 / 16.63 ms │      15.93 / 16.10 ±0.17 / 16.31 ms │ no change │
│ QQuery 17 │ 72.73 / 73.35 ±0.48 / 73.84 ms │      72.65 / 73.29 ±0.63 / 74.15 ms │ no change │
│ QQuery 18 │ 76.51 / 77.81 ±0.95 / 79.25 ms │      77.26 / 78.34 ±0.80 / 79.11 ms │ no change │
│ QQuery 19 │ 37.26 / 37.75 ±0.46 / 38.41 ms │      37.19 / 37.70 ±0.42 / 38.20 ms │ no change │
│ QQuery 20 │ 40.35 / 40.58 ±0.20 / 40.81 ms │      39.93 / 40.83 ±0.75 / 42.02 ms │ no change │
│ QQuery 21 │ 63.20 / 64.31 ±0.90 / 65.87 ms │      63.67 / 65.55 ±1.15 / 66.76 ms │ no change │
│ QQuery 22 │ 17.84 / 18.46 ±0.63 / 19.55 ms │      17.74 / 18.09 ±0.27 / 18.41 ms │ no change │
└───────────┴────────────────────────────────┴─────────────────────────────────────┴───────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┓
┃ Benchmark Summary                                  ┃          ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━┩
│ Total Time (HEAD)                                  │ 891.79ms │
│ Total Time (feat_sort-file-groups-by-statistics)   │ 895.87ms │
│ Average Time (HEAD)                                │  40.54ms │
│ Average Time (feat_sort-file-groups-by-statistics) │  40.72ms │
│ Queries Faster                                     │        0 │
│ Queries Slower                                     │        0 │
│ Queries with No Change                             │       22 │
│ Queries with Failure                               │        0 │
└────────────────────────────────────────────────────┴──────────┘

Resource Usage

tpch — base (merge-base)

Metric Value
Wall time 4.7s
Peak memory 4.0 GiB
Avg memory 3.6 GiB
CPU user 33.1s
CPU sys 2.9s
Disk read 0 B
Disk write 136.0 KiB

tpch — branch

Metric Value
Wall time 4.7s
Peak memory 4.1 GiB
Avg memory 3.6 GiB
CPU user 33.2s
CPU sys 3.0s
Disk read 0 B
Disk write 72.0 KiB

File an issue against this benchmark runner

@adriangbot
Copy link
Copy Markdown

🤖 Benchmark completed (GKE) | trigger

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

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 feat_sort-file-groups-by-statistics
--------------------
Benchmark tpcds_sf1.json
--------------------
┏━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Query     ┃                                     HEAD ┃      feat_sort-file-groups-by-statistics ┃        Change ┃
┡━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ QQuery 1  │           44.02 / 44.88 ±0.68 / 46.00 ms │           43.49 / 44.07 ±0.80 / 45.60 ms │     no change │
│ QQuery 2  │        145.00 / 146.83 ±1.64 / 149.04 ms │        146.23 / 147.31 ±0.77 / 148.21 ms │     no change │
│ QQuery 3  │        114.94 / 116.37 ±1.06 / 117.51 ms │        114.99 / 115.68 ±0.65 / 116.85 ms │     no change │
│ QQuery 4  │    1341.58 / 1361.40 ±15.96 / 1387.53 ms │    1315.35 / 1341.73 ±22.34 / 1379.48 ms │     no change │
│ QQuery 5  │        172.28 / 173.70 ±0.86 / 174.63 ms │        174.38 / 176.65 ±1.49 / 178.75 ms │     no change │
│ QQuery 6  │    1021.69 / 1050.40 ±26.62 / 1094.54 ms │    1028.33 / 1065.22 ±22.58 / 1098.29 ms │     no change │
│ QQuery 7  │        357.39 / 362.84 ±4.75 / 370.20 ms │        355.20 / 357.14 ±1.53 / 358.45 ms │     no change │
│ QQuery 8  │        117.02 / 118.32 ±0.84 / 119.63 ms │        116.28 / 117.48 ±0.93 / 118.70 ms │     no change │
│ QQuery 9  │        101.91 / 106.97 ±6.16 / 118.31 ms │       102.49 / 110.09 ±10.34 / 130.28 ms │     no change │
│ QQuery 10 │        108.44 / 110.12 ±0.86 / 110.79 ms │        109.28 / 111.17 ±1.23 / 113.04 ms │     no change │
│ QQuery 11 │      970.60 / 984.53 ±10.65 / 1002.55 ms │       900.92 / 916.07 ±12.11 / 932.59 ms │ +1.07x faster │
│ QQuery 12 │           46.33 / 47.74 ±1.27 / 49.62 ms │           45.74 / 46.11 ±0.26 / 46.46 ms │     no change │
│ QQuery 13 │        399.74 / 406.08 ±4.56 / 412.16 ms │        401.23 / 405.03 ±2.24 / 407.75 ms │     no change │
│ QQuery 14 │     1025.97 / 1032.56 ±3.83 / 1036.90 ms │     1024.30 / 1036.16 ±7.79 / 1047.17 ms │     no change │
│ QQuery 15 │           15.96 / 16.83 ±0.80 / 18.33 ms │           15.61 / 16.88 ±1.26 / 19.29 ms │     no change │
│ QQuery 16 │           41.68 / 42.37 ±0.62 / 43.47 ms │           41.34 / 42.60 ±1.36 / 45.23 ms │     no change │
│ QQuery 17 │        241.81 / 243.68 ±1.16 / 245.16 ms │        242.54 / 243.88 ±1.33 / 245.61 ms │     no change │
│ QQuery 18 │        129.12 / 131.11 ±1.42 / 133.16 ms │        129.08 / 130.17 ±0.59 / 130.74 ms │     no change │
│ QQuery 19 │        155.65 / 158.64 ±1.70 / 160.63 ms │        158.98 / 160.08 ±1.04 / 161.68 ms │     no change │
│ QQuery 20 │           14.09 / 14.64 ±0.45 / 15.32 ms │           14.15 / 14.81 ±0.69 / 16.12 ms │     no change │
│ QQuery 21 │           19.80 / 20.29 ±0.48 / 21.16 ms │           20.23 / 20.88 ±0.77 / 22.29 ms │     no change │
│ QQuery 22 │        490.50 / 495.75 ±4.75 / 504.62 ms │        481.56 / 486.06 ±4.01 / 492.21 ms │     no change │
│ QQuery 23 │       899.07 / 911.20 ±10.71 / 924.34 ms │        894.57 / 898.55 ±3.01 / 903.73 ms │     no change │
│ QQuery 24 │        420.82 / 423.90 ±2.41 / 427.52 ms │        414.21 / 418.97 ±3.22 / 423.87 ms │     no change │
│ QQuery 25 │        359.15 / 361.11 ±1.47 / 362.88 ms │        355.09 / 357.18 ±2.17 / 360.04 ms │     no change │
│ QQuery 26 │           80.92 / 83.54 ±2.22 / 87.26 ms │           82.96 / 84.21 ±1.30 / 85.93 ms │     no change │
│ QQuery 27 │        350.83 / 353.79 ±2.57 / 357.70 ms │        350.86 / 352.55 ±1.36 / 354.47 ms │     no change │
│ QQuery 28 │        149.60 / 150.42 ±0.69 / 151.68 ms │        149.03 / 151.68 ±1.97 / 154.36 ms │     no change │
│ QQuery 29 │        301.58 / 303.32 ±1.71 / 306.48 ms │        299.18 / 302.15 ±2.38 / 305.11 ms │     no change │
│ QQuery 30 │           43.14 / 45.33 ±1.67 / 47.60 ms │           43.70 / 45.48 ±1.45 / 47.86 ms │     no change │
│ QQuery 31 │        170.73 / 174.14 ±2.65 / 178.49 ms │        173.92 / 175.20 ±0.72 / 176.12 ms │     no change │
│ QQuery 32 │           58.51 / 58.80 ±0.31 / 59.36 ms │           57.73 / 58.09 ±0.31 / 58.48 ms │     no change │
│ QQuery 33 │        141.23 / 143.57 ±1.65 / 145.76 ms │        142.02 / 143.39 ±1.32 / 145.86 ms │     no change │
│ QQuery 34 │        105.68 / 109.16 ±2.34 / 112.98 ms │        107.45 / 108.37 ±0.67 / 109.51 ms │     no change │
│ QQuery 35 │        108.31 / 110.76 ±1.60 / 112.99 ms │        104.69 / 109.91 ±3.35 / 113.80 ms │     no change │
│ QQuery 36 │        219.25 / 224.16 ±3.52 / 228.59 ms │        211.95 / 218.93 ±4.59 / 225.52 ms │     no change │
│ QQuery 37 │        178.14 / 181.78 ±3.07 / 186.48 ms │        179.23 / 181.10 ±1.12 / 182.55 ms │     no change │
│ QQuery 38 │           86.93 / 89.92 ±2.76 / 94.83 ms │           84.63 / 89.30 ±3.28 / 92.83 ms │     no change │
│ QQuery 39 │        128.96 / 130.99 ±1.08 / 132.20 ms │        127.22 / 129.67 ±1.26 / 130.67 ms │     no change │
│ QQuery 40 │        114.88 / 119.88 ±6.93 / 133.55 ms │        113.90 / 118.59 ±5.25 / 128.03 ms │     no change │
│ QQuery 41 │           14.63 / 15.50 ±0.82 / 16.68 ms │           14.39 / 15.63 ±0.90 / 16.68 ms │     no change │
│ QQuery 42 │        108.95 / 111.09 ±1.78 / 114.13 ms │        108.38 / 111.04 ±1.87 / 113.63 ms │     no change │
│ QQuery 43 │           84.89 / 85.89 ±0.90 / 87.38 ms │           84.87 / 85.12 ±0.22 / 85.47 ms │     no change │
│ QQuery 44 │           11.93 / 12.43 ±0.57 / 13.49 ms │           11.58 / 12.36 ±1.01 / 14.34 ms │     no change │
│ QQuery 45 │           52.88 / 54.82 ±1.11 / 56.03 ms │           51.43 / 53.29 ±1.23 / 55.07 ms │     no change │
│ QQuery 46 │        231.56 / 235.66 ±3.68 / 240.49 ms │        231.04 / 235.07 ±2.54 / 238.09 ms │     no change │
│ QQuery 47 │        699.32 / 708.94 ±9.38 / 724.80 ms │        682.58 / 696.11 ±7.01 / 702.30 ms │     no change │
│ QQuery 48 │        286.29 / 288.94 ±1.49 / 290.59 ms │        285.58 / 291.70 ±3.86 / 296.60 ms │     no change │
│ QQuery 49 │        256.45 / 259.33 ±2.88 / 264.42 ms │        254.71 / 259.25 ±2.56 / 261.77 ms │     no change │
│ QQuery 50 │        231.40 / 237.33 ±4.06 / 243.71 ms │        228.61 / 235.93 ±4.79 / 240.64 ms │     no change │
│ QQuery 51 │        180.77 / 185.21 ±2.98 / 189.43 ms │        178.87 / 183.95 ±3.23 / 187.53 ms │     no change │
│ QQuery 52 │        109.34 / 111.06 ±1.13 / 112.85 ms │        108.81 / 111.30 ±2.29 / 115.35 ms │     no change │
│ QQuery 53 │        103.70 / 105.12 ±0.93 / 106.56 ms │        104.22 / 105.23 ±0.92 / 106.58 ms │     no change │
│ QQuery 54 │        149.29 / 150.69 ±0.91 / 151.98 ms │        148.47 / 150.54 ±1.79 / 153.22 ms │     no change │
│ QQuery 55 │        108.39 / 109.13 ±0.91 / 110.53 ms │        109.10 / 110.29 ±1.72 / 113.65 ms │     no change │
│ QQuery 56 │        142.65 / 143.71 ±0.78 / 144.94 ms │        143.57 / 145.04 ±0.78 / 145.87 ms │     no change │
│ QQuery 57 │        173.64 / 177.69 ±2.53 / 181.29 ms │        172.27 / 174.91 ±1.49 / 176.79 ms │     no change │
│ QQuery 58 │        302.41 / 305.31 ±2.35 / 308.98 ms │        307.18 / 312.25 ±5.09 / 321.73 ms │     no change │
│ QQuery 59 │        198.81 / 202.17 ±3.11 / 207.62 ms │        197.42 / 201.13 ±2.44 / 204.45 ms │     no change │
│ QQuery 60 │        144.61 / 146.75 ±1.67 / 148.47 ms │        147.19 / 150.76 ±5.75 / 162.23 ms │     no change │
│ QQuery 61 │        173.46 / 174.20 ±0.82 / 175.25 ms │        170.42 / 173.07 ±1.55 / 175.07 ms │     no change │
│ QQuery 62 │      917.35 / 976.62 ±38.37 / 1018.85 ms │       914.54 / 934.46 ±14.57 / 948.84 ms │     no change │
│ QQuery 63 │        106.24 / 107.94 ±1.73 / 110.22 ms │        106.00 / 108.74 ±2.15 / 111.80 ms │     no change │
│ QQuery 64 │        707.02 / 713.96 ±4.26 / 719.13 ms │        698.01 / 705.85 ±4.08 / 709.96 ms │     no change │
│ QQuery 65 │        250.04 / 257.16 ±3.92 / 260.70 ms │        250.29 / 256.38 ±3.34 / 259.06 ms │     no change │
│ QQuery 66 │        245.16 / 251.25 ±6.23 / 261.55 ms │       243.65 / 257.30 ±14.72 / 283.65 ms │     no change │
│ QQuery 67 │        313.26 / 319.89 ±6.19 / 331.07 ms │        311.28 / 315.51 ±3.42 / 321.14 ms │     no change │
│ QQuery 68 │        279.74 / 284.48 ±2.74 / 288.19 ms │        279.59 / 283.35 ±3.33 / 289.44 ms │     no change │
│ QQuery 69 │        102.53 / 104.40 ±1.03 / 105.51 ms │        104.22 / 105.23 ±1.24 / 107.61 ms │     no change │
│ QQuery 70 │        348.61 / 352.06 ±5.01 / 361.75 ms │       350.96 / 366.09 ±15.00 / 392.96 ms │     no change │
│ QQuery 71 │        136.19 / 138.97 ±2.18 / 141.54 ms │        135.78 / 138.94 ±2.01 / 141.80 ms │     no change │
│ QQuery 72 │        710.85 / 718.42 ±7.67 / 732.93 ms │        710.49 / 716.02 ±4.11 / 721.62 ms │     no change │
│ QQuery 73 │        102.72 / 105.57 ±1.76 / 107.55 ms │        103.63 / 104.99 ±0.98 / 106.64 ms │     no change │
│ QQuery 74 │        549.96 / 556.53 ±4.53 / 561.74 ms │        555.32 / 563.21 ±8.57 / 576.93 ms │     no change │
│ QQuery 75 │        276.31 / 278.53 ±1.95 / 281.63 ms │        275.59 / 280.25 ±2.79 / 283.29 ms │     no change │
│ QQuery 76 │        133.97 / 135.19 ±1.45 / 138.01 ms │        134.75 / 135.34 ±0.67 / 136.56 ms │     no change │
│ QQuery 77 │        185.93 / 189.10 ±2.00 / 191.68 ms │        191.16 / 191.75 ±0.38 / 192.05 ms │     no change │
│ QQuery 78 │        351.01 / 352.90 ±2.18 / 356.25 ms │        354.79 / 358.47 ±2.57 / 361.92 ms │     no change │
│ QQuery 79 │        230.33 / 234.65 ±4.26 / 240.00 ms │        234.45 / 237.20 ±3.03 / 242.81 ms │     no change │
│ QQuery 80 │        330.32 / 333.77 ±2.04 / 335.85 ms │        331.71 / 335.27 ±1.99 / 337.79 ms │     no change │
│ QQuery 81 │           26.55 / 27.10 ±0.49 / 27.84 ms │           26.42 / 27.98 ±1.49 / 30.13 ms │     no change │
│ QQuery 82 │        199.18 / 201.17 ±1.34 / 202.82 ms │        201.61 / 205.28 ±2.70 / 208.85 ms │     no change │
│ QQuery 83 │           38.69 / 40.41 ±1.58 / 42.97 ms │           40.01 / 41.13 ±1.09 / 43.20 ms │     no change │
│ QQuery 84 │           49.51 / 50.17 ±0.45 / 50.71 ms │           48.07 / 50.51 ±1.98 / 54.08 ms │     no change │
│ QQuery 85 │        147.71 / 150.31 ±2.00 / 153.14 ms │        150.11 / 151.04 ±1.39 / 153.77 ms │     no change │
│ QQuery 86 │           38.61 / 39.85 ±1.16 / 41.74 ms │           38.90 / 40.01 ±1.10 / 41.94 ms │     no change │
│ QQuery 87 │           85.62 / 89.43 ±3.72 / 96.14 ms │           88.62 / 91.05 ±1.81 / 93.18 ms │     no change │
│ QQuery 88 │        100.49 / 101.33 ±0.55 / 102.04 ms │        102.18 / 103.60 ±1.25 / 105.88 ms │     no change │
│ QQuery 89 │        118.53 / 119.33 ±0.57 / 120.20 ms │        117.01 / 119.80 ±1.72 / 122.41 ms │     no change │
│ QQuery 90 │           23.82 / 24.92 ±1.12 / 26.83 ms │           23.91 / 24.93 ±1.14 / 27.08 ms │     no change │
│ QQuery 91 │           62.58 / 64.14 ±1.01 / 65.41 ms │           61.43 / 64.97 ±1.95 / 67.12 ms │     no change │
│ QQuery 92 │           56.88 / 58.18 ±1.28 / 60.06 ms │           56.96 / 58.78 ±1.42 / 61.32 ms │     no change │
│ QQuery 93 │        191.67 / 193.63 ±1.46 / 195.60 ms │        191.97 / 195.01 ±1.75 / 197.34 ms │     no change │
│ QQuery 94 │           61.48 / 62.39 ±0.66 / 63.23 ms │           62.26 / 63.94 ±1.19 / 65.26 ms │     no change │
│ QQuery 95 │        135.24 / 136.01 ±0.58 / 136.80 ms │        136.14 / 138.48 ±1.50 / 140.47 ms │     no change │
│ QQuery 96 │           72.21 / 74.70 ±2.03 / 78.25 ms │           75.20 / 76.70 ±0.93 / 78.01 ms │     no change │
│ QQuery 97 │        127.84 / 131.72 ±2.24 / 134.68 ms │        130.92 / 133.13 ±1.53 / 135.40 ms │     no change │
│ QQuery 98 │        152.50 / 154.94 ±1.90 / 157.73 ms │        153.70 / 156.80 ±1.90 / 158.83 ms │     no change │
│ QQuery 99 │ 10732.85 / 10766.55 ±18.72 / 10789.45 ms │ 10874.79 / 10909.05 ±18.77 / 10930.81 ms │     no change │
└───────────┴──────────────────────────────────────────┴──────────────────────────────────────────┴───────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┓
┃ Benchmark Summary                                  ┃            ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━┩
│ Total Time (HEAD)                                  │ 33880.49ms │
│ Total Time (feat_sort-file-groups-by-statistics)   │ 33909.12ms │
│ Average Time (HEAD)                                │   342.23ms │
│ Average Time (feat_sort-file-groups-by-statistics) │   342.52ms │
│ Queries Faster                                     │          1 │
│ Queries Slower                                     │          0 │
│ Queries with No Change                             │         98 │
│ Queries with Failure                               │          0 │
└────────────────────────────────────────────────────┴────────────┘

Resource Usage

tpcds — base (merge-base)

Metric Value
Wall time 169.7s
Peak memory 5.7 GiB
Avg memory 4.6 GiB
CPU user 272.0s
CPU sys 18.9s
Disk read 0 B
Disk write 707.3 MiB

tpcds — branch

Metric Value
Wall time 169.8s
Peak memory 5.5 GiB
Avg memory 4.4 GiB
CPU user 271.0s
CPU sys 19.1s
Disk read 0 B
Disk write 776.0 KiB

File an issue against this benchmark runner

@adriangbot
Copy link
Copy Markdown

🤖 Benchmark completed (GKE) | trigger

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

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 feat_sort-file-groups-by-statistics
--------------------
Benchmark clickbench_partitioned.json
--------------------
┏━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Query     ┃                                  HEAD ┃   feat_sort-file-groups-by-statistics ┃        Change ┃
┡━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ QQuery 0  │          1.35 / 4.67 ±6.49 / 17.65 ms │          1.31 / 4.54 ±6.32 / 17.18 ms │     no change │
│ QQuery 1  │        14.38 / 14.78 ±0.21 / 14.96 ms │        14.24 / 14.64 ±0.20 / 14.78 ms │     no change │
│ QQuery 2  │        43.97 / 44.30 ±0.19 / 44.49 ms │        44.89 / 45.24 ±0.26 / 45.58 ms │     no change │
│ QQuery 3  │        43.63 / 44.81 ±0.99 / 46.48 ms │        43.91 / 44.41 ±0.62 / 45.62 ms │     no change │
│ QQuery 4  │     294.40 / 298.97 ±3.74 / 305.25 ms │     290.63 / 298.92 ±7.74 / 313.18 ms │     no change │
│ QQuery 5  │     352.42 / 357.91 ±5.25 / 366.00 ms │     344.57 / 348.65 ±2.69 / 351.92 ms │     no change │
│ QQuery 6  │           5.53 / 7.01 ±1.39 / 9.24 ms │           4.88 / 6.43 ±1.10 / 8.20 ms │ +1.09x faster │
│ QQuery 7  │        17.04 / 17.20 ±0.15 / 17.47 ms │        16.83 / 17.78 ±1.07 / 19.72 ms │     no change │
│ QQuery 8  │     425.90 / 436.12 ±6.63 / 443.24 ms │     422.01 / 432.82 ±6.91 / 442.22 ms │     no change │
│ QQuery 9  │    663.35 / 680.08 ±15.03 / 705.76 ms │     652.38 / 656.82 ±5.48 / 667.28 ms │     no change │
│ QQuery 10 │        92.26 / 96.14 ±2.91 / 99.68 ms │       91.60 / 95.74 ±3.62 / 101.46 ms │     no change │
│ QQuery 11 │     104.19 / 107.29 ±2.15 / 110.94 ms │     104.41 / 105.28 ±0.95 / 106.89 ms │     no change │
│ QQuery 12 │     351.75 / 356.30 ±3.53 / 359.94 ms │     345.87 / 353.56 ±5.43 / 361.43 ms │     no change │
│ QQuery 13 │    486.97 / 512.17 ±27.14 / 555.93 ms │    461.81 / 481.11 ±12.80 / 499.00 ms │ +1.06x faster │
│ QQuery 14 │     352.77 / 358.48 ±5.57 / 367.99 ms │     353.41 / 361.30 ±5.06 / 367.41 ms │     no change │
│ QQuery 15 │    370.93 / 408.33 ±20.31 / 428.45 ms │    364.80 / 381.27 ±12.26 / 396.42 ms │ +1.07x faster │
│ QQuery 16 │    732.23 / 768.55 ±40.37 / 832.55 ms │    729.00 / 751.30 ±14.35 / 768.89 ms │     no change │
│ QQuery 17 │    718.26 / 727.93 ±11.23 / 749.89 ms │     718.67 / 725.62 ±5.29 / 732.67 ms │     no change │
│ QQuery 18 │ 1380.34 / 1431.09 ±51.53 / 1521.24 ms │ 1472.19 / 1496.11 ±28.04 / 1549.89 ms │     no change │
│ QQuery 19 │        37.27 / 38.26 ±1.18 / 39.92 ms │        36.69 / 38.30 ±0.97 / 39.72 ms │     no change │
│ QQuery 20 │    701.66 / 718.37 ±17.71 / 746.84 ms │    715.84 / 726.31 ±12.61 / 749.81 ms │     no change │
│ QQuery 21 │     751.75 / 754.26 ±2.95 / 759.78 ms │     760.74 / 762.76 ±1.61 / 765.19 ms │     no change │
│ QQuery 22 │  1121.24 / 1131.92 ±9.38 / 1147.90 ms │  1132.79 / 1137.91 ±3.11 / 1141.01 ms │     no change │
│ QQuery 23 │ 3088.40 / 3105.46 ±12.82 / 3121.82 ms │  3088.31 / 3098.41 ±7.23 / 3110.47 ms │     no change │
│ QQuery 24 │     100.47 / 103.83 ±2.04 / 105.88 ms │      96.57 / 100.78 ±2.64 / 104.15 ms │     no change │
│ QQuery 25 │     140.42 / 141.71 ±1.07 / 142.86 ms │     136.43 / 138.60 ±1.87 / 142.01 ms │     no change │
│ QQuery 26 │      98.76 / 102.77 ±3.33 / 107.40 ms │     100.86 / 103.39 ±2.21 / 105.89 ms │     no change │
│ QQuery 27 │    841.69 / 854.95 ±13.92 / 879.72 ms │     848.63 / 855.26 ±5.22 / 861.60 ms │     no change │
│ QQuery 28 │ 7723.29 / 7755.32 ±24.29 / 7795.51 ms │ 7718.14 / 7794.40 ±40.10 / 7832.70 ms │     no change │
│ QQuery 29 │        50.45 / 54.30 ±3.51 / 60.90 ms │        50.47 / 56.85 ±7.54 / 71.51 ms │     no change │
│ QQuery 30 │     357.85 / 363.89 ±4.15 / 370.30 ms │     364.53 / 371.59 ±3.85 / 374.57 ms │     no change │
│ QQuery 31 │    375.85 / 390.40 ±13.93 / 416.33 ms │     370.93 / 382.94 ±7.22 / 392.45 ms │     no change │
│ QQuery 32 │ 1031.92 / 1059.40 ±28.32 / 1111.91 ms │ 1049.04 / 1079.45 ±30.37 / 1128.60 ms │     no change │
│ QQuery 33 │  1456.64 / 1463.45 ±5.34 / 1471.80 ms │ 1489.84 / 1510.22 ±20.02 / 1547.16 ms │     no change │
│ QQuery 34 │ 1457.74 / 1479.70 ±14.62 / 1497.78 ms │  1496.16 / 1505.29 ±7.77 / 1519.55 ms │     no change │
│ QQuery 35 │     384.08 / 392.72 ±8.10 / 405.96 ms │     400.53 / 409.65 ±6.87 / 417.46 ms │     no change │
│ QQuery 36 │     111.95 / 120.51 ±4.57 / 124.52 ms │     116.30 / 123.86 ±4.86 / 130.86 ms │     no change │
│ QQuery 37 │        49.42 / 50.86 ±1.41 / 53.44 ms │        48.54 / 51.28 ±1.92 / 54.06 ms │     no change │
│ QQuery 38 │        75.44 / 77.73 ±1.87 / 79.67 ms │        77.94 / 79.70 ±1.82 / 82.62 ms │     no change │
│ QQuery 39 │     208.41 / 218.77 ±8.09 / 230.52 ms │     216.98 / 226.86 ±6.30 / 236.52 ms │     no change │
│ QQuery 40 │        23.66 / 26.32 ±2.19 / 29.99 ms │        25.32 / 27.64 ±1.52 / 29.93 ms │  1.05x slower │
│ QQuery 41 │        19.78 / 21.12 ±0.91 / 22.40 ms │        19.89 / 21.84 ±1.11 / 23.34 ms │     no change │
│ QQuery 42 │        19.30 / 20.68 ±1.38 / 23.28 ms │        20.40 / 21.06 ±0.71 / 22.27 ms │     no change │
└───────────┴───────────────────────────────────────┴───────────────────────────────────────┴───────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┓
┃ Benchmark Summary                                  ┃            ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━┩
│ Total Time (HEAD)                                  │ 27118.84ms │
│ Total Time (feat_sort-file-groups-by-statistics)   │ 27245.93ms │
│ Average Time (HEAD)                                │   630.67ms │
│ Average Time (feat_sort-file-groups-by-statistics) │   633.63ms │
│ Queries Faster                                     │          3 │
│ Queries Slower                                     │          1 │
│ Queries with No Change                             │         39 │
│ Queries with Failure                               │          0 │
└────────────────────────────────────────────────────┴────────────┘

Resource Usage

clickbench_partitioned — base (merge-base)

Metric Value
Wall time 136.8s
Peak memory 41.3 GiB
Avg memory 33.4 GiB
CPU user 1286.4s
CPU sys 91.0s
Disk read 0 B
Disk write 3.3 GiB

clickbench_partitioned — branch

Metric Value
Wall time 137.5s
Peak memory 45.1 GiB
Avg memory 32.3 GiB
CPU user 1289.5s
CPU sys 93.0s
Disk read 0 B
Disk write 748.0 KiB

File an issue against this benchmark runner

@zhuqi-lucas zhuqi-lucas force-pushed the feat/sort-file-groups-by-statistics branch from a79cbdf to 5e3eaac Compare March 27, 2026 15:33
@zhuqi-lucas
Copy link
Copy Markdown
Contributor Author

zhuqi-lucas commented Mar 27, 2026

Thanks for the review @adriangb! I've addressed all feedback:

  • Benchmark split: Removed benchmark code from this PR, will submit as a follow-up PR after this PR done
  • "Unsupported if already in order": Clarified the comment — expanded to explain that Unsupported means no change was made to the plan (files were already in the correct order, nothing to optimize)
  • Row-group-level stats reordering: Great idea for a follow-up — same concept as file-level reordering but at finer granularity, especially powerful with morselized scans
  • Lopsided partitions: Minimal impact in practice since file count >> partition count, imbalance is at most 1 extra file

@adriangb
Copy link
Copy Markdown
Contributor

Benchmark split: Removed benchmark code from this PR, will submit as a follow-up PR after this PR done

I'd like to do the opposite: commit the benchmarks and SLT tests as a precursor PR, then rebase this branch so we can see just the diff in benchmarks / SLT.

@zhuqi-lucas
Copy link
Copy Markdown
Contributor Author

Benchmark split: Removed benchmark code from this PR, will submit as a follow-up PR after this PR done

I'd like to do the opposite: commit the benchmarks and SLT tests as a precursor PR, then rebase this branch so we can see just the diff in benchmarks / SLT.

Good point, i agree.

@zhuqi-lucas zhuqi-lucas force-pushed the feat/sort-file-groups-by-statistics branch 2 times, most recently from 397a967 to f5a3da8 Compare March 28, 2026 02:14
@zhuqi-lucas
Copy link
Copy Markdown
Contributor Author

@adriangb I've removed the redistribute_files_across_groups_by_statistics logic after deeper analysis. Here's the reasoning:

The problem with redistribution:

The planning-phase bin-packing produces interleaved groups like:

Group 0: [f1(1-10), f3(21-30)]
Group 1: [f2(11-20), f4(31-40)]

If we redistribute consecutively:

Group 0: [f1(1-10), f2(11-20)]    ← all values < Group 1
Group 1: [f3(21-30), f4(31-40)]

This looks cleaner, but SPM would read all of Group 0 first (values always smaller), then Group 1. The other partition sits completely idle — effectively single-threaded I/O.

Why interleaved is better:

With the original interleaved groups, SPM alternates pulling from both partitions:

SPM: pull P0 [1-10] → pull P1 [11-20] → pull P0 [21-30] → pull P1 [31-40]

Both partitions are actively scanning files simultaneously — true parallel I/O.

The core optimization (per-partition sort elimination via statistics-based non-overlapping detection) works the same either way. So I removed the redistribution to keep the code simpler and preserve parallel I/O.

Latest commit: removed redistribute_files_across_groups_by_statistics, updated comments with the reasoning, and replaced the redistribution tests with a test that verifies groups are preserved as-is.

zhuqi-lucas added a commit to zhuqi-lucas/arrow-datafusion that referenced this pull request Mar 29, 2026
Add benchmark and integration tests for sort pushdown optimization
as a precursor to the core optimization PR (apache#21182).

Benchmark: new `sort-pushdown` subcommand with 4 queries testing
sort elimination (ASC full scan, ASC LIMIT, wide full, wide LIMIT).

SLT tests (5 new groups):
- Test A: Non-overlapping files + WITH ORDER → Sort eliminated
- Test B: Overlapping files → SortExec retained
- Test C: LIMIT queries (ASC sort elimination + DESC reverse scan)
- Test D: target_partitions=2 → SPM + per-partition sort elimination
- Test E: Inferred ordering from Parquet metadata (no WITH ORDER)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@zhuqi-lucas
Copy link
Copy Markdown
Contributor Author

@adriangb Updated as you suggested — created a precursor PR with both benchmarks and SLT tests: #21213

The SLT tests (Test A-E) use pre-optimization expected plans. Once #21213 merges and I rebase this PR, the diff here will clearly show how the optimization changes the test expectations (e.g., Test B's file order changes from [x, y, z] to [z, y, x] due to statistics-based reordering).

zhuqi-lucas added a commit to zhuqi-lucas/arrow-datafusion that referenced this pull request Mar 30, 2026
Add benchmark and integration tests for sort pushdown optimization
as a precursor to the core optimization PR (apache#21182).

Benchmark: new `sort-pushdown` subcommand with 4 queries testing
sort elimination (ASC full scan, ASC LIMIT, wide full, wide LIMIT).

SLT tests (5 new groups):
- Test A: Non-overlapping files + WITH ORDER → Sort eliminated
- Test B: Overlapping files → SortExec retained
- Test C: LIMIT queries (ASC sort elimination + DESC reverse scan)
- Test D: target_partitions=2 → SPM + per-partition sort elimination
- Test E: Inferred ordering from Parquet metadata (no WITH ORDER)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@adriangb
Copy link
Copy Markdown
Contributor

adriangb commented Apr 6, 2026

8MB was too small for wide-row full scans (Q3: SELECT * with 16 columns),
causing SPM to stall on I/O. 64MB per partition is still strictly less
than the SortExec it replaces (which buffers entire partition in memory).
BufferExec integrates with MemoryPool so it won't cause OOM.

I think this is right. Basically: SortExec is "unlimited" buffering. IMO we could go even higher if we have to a pick a number (although perhaps it should be configurable if it isn't already) - something like 512MB. If the partition is smaller it will never be hit. If it is larger or we run out of memory it will spill.

But let's see what the numbers look like with 64MB.

@adriangbot
Copy link
Copy Markdown

🤖 Benchmark completed (GKE) | trigger

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

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 feat_sort-file-groups-by-statistics
--------------------
Benchmark sort_pushdown_sorted.json
--------------------
┏━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Query ┃                              HEAD ┃ feat_sort-file-groups-by-statistics ┃        Change ┃
┡━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ Q1    │ 158.16 / 158.64 ±0.38 / 159.16 ms │   121.48 / 123.31 ±1.20 / 124.65 ms │ +1.29x faster │
│ Q2    │    12.38 / 12.61 ±0.19 / 12.90 ms │         2.49 / 2.70 ±0.27 / 3.23 ms │ +4.66x faster │
│ Q3    │ 365.09 / 367.46 ±1.99 / 371.08 ms │   325.28 / 333.90 ±5.79 / 342.48 ms │ +1.10x faster │
│ Q4    │    53.62 / 54.45 ±1.07 / 56.52 ms │         5.54 / 5.97 ±0.58 / 7.11 ms │ +9.12x faster │
└───────┴───────────────────────────────────┴─────────────────────────────────────┴───────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┓
┃ Benchmark Summary                                  ┃          ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━┩
│ Total Time (HEAD)                                  │ 593.17ms │
│ Total Time (feat_sort-file-groups-by-statistics)   │ 465.89ms │
│ Average Time (HEAD)                                │ 148.29ms │
│ Average Time (feat_sort-file-groups-by-statistics) │ 116.47ms │
│ Queries Faster                                     │        4 │
│ Queries Slower                                     │        0 │
│ Queries with No Change                             │        0 │
│ Queries with Failure                               │        0 │
└────────────────────────────────────────────────────┴──────────┘

Resource Usage

sort_pushdown_sorted — base (merge-base)

Metric Value
Wall time 3.3s
Peak memory 5.2 GiB
Avg memory 3.8 GiB
CPU user 9.8s
CPU sys 1.0s
Peak spill 0 B

sort_pushdown_sorted — branch

Metric Value
Wall time 2.6s
Peak memory 4.3 GiB
Avg memory 3.4 GiB
CPU user 5.6s
CPU sys 0.8s
Peak spill 0 B

File an issue against this benchmark runner

@zhuqi-lucas
Copy link
Copy Markdown
Contributor Author

8MB was too small for wide-row full scans (Q3: SELECT * with 16 columns),
causing SPM to stall on I/O. 64MB per partition is still strictly less
than the SortExec it replaces (which buffers entire partition in memory).
BufferExec integrates with MemoryPool so it won't cause OOM.

I think this is right. Basically: SortExec is "unlimited" buffering. IMO we could go even higher if we have to a pick a number (although perhaps it should be configurable if it isn't already) - something like 512MB. If the partition is smaller it will never be hit. If it is larger or we run out of memory it will spill.

But let's see what the numbers look like with 64MB.

Comparing HEAD and feat_sort-file-groups-by-statistics
--------------------
Benchmark sort_pushdown_sorted.json
--------------------
┏━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ QueryHEAD ┃ feat_sort-file-groups-by-statistics ┃        Change ┃
┡━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ Q1158.16 / 158.64 ±0.38 / 159.16 ms │   121.48 / 123.31 ±1.20 / 124.65 ms │ +1.29x faster │
│ Q212.38 / 12.61 ±0.19 / 12.90 ms │         2.49 / 2.70 ±0.27 / 3.23 ms │ +4.66x faster │
│ Q3365.09 / 367.46 ±1.99 / 371.08 ms │   325.28 / 333.90 ±5.79 / 342.48 ms │ +1.10x faster │
│ Q453.62 / 54.45 ±1.07 / 56.52 ms │         5.54 / 5.97 ±0.58 / 7.11 ms │ +9.12x faster │
└───────┴───────────────────────────────────┴─────────────────────────────────────┴───────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┓
┃ Benchmark Summary                                  ┃          ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━┩
│ Total Time (HEAD)593.17ms │
│ Total Time (feat_sort-file-groups-by-statistics)465.89ms │
│ Average Time (HEAD)148.29ms │
│ Average Time (feat_sort-file-groups-by-statistics)116.47ms │
│ Queries Faster4 │
│ Queries Slower0 │
│ Queries with No Change0 │
│ Queries with Failure0 │
└────────────────────────────────────────────────────┴──────────┘

The result is amazing @adriangb !

@adriangb
Copy link
Copy Markdown
Contributor

adriangb commented Apr 6, 2026

And lower memory usage!!

I just wonder if we should bump the number up higher so that no matter the size of the rows in the workload / size of batches we don't get IO stalling.

@alamb I wonder what you think?

@zhuqi-lucas
Copy link
Copy Markdown
Contributor Author

run benchmarks

@adriangbot
Copy link
Copy Markdown

🤖 Benchmark running (GKE) | trigger
Instance: c4a-highmem-16 (12 vCPU / 65 GiB) | Linux bench-c4190456325-872-msqqj 6.12.55+ #1 SMP Sun Feb 1 08:59:41 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 feat/sort-file-groups-by-statistics (790cbce) to c17c87c (merge-base) diff using: 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-c4190456325-871-mrx6f 6.12.55+ #1 SMP Sun Feb 1 08:59:41 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 feat/sort-file-groups-by-statistics (790cbce) to c17c87c (merge-base) diff using: tpcds
Results will be posted here when complete


File an issue against this benchmark runner

@zhuqi-lucas
Copy link
Copy Markdown
Contributor Author

And lower memory usage!!

I just wonder if we should bump the number up higher so that no matter the size of the rows in the workload / size of batches we don't get IO stalling.

@alamb I wonder what you think?

Just triggered other benchmarks, let's see if there are new regressions.

@adriangbot
Copy link
Copy Markdown

🤖 Benchmark running (GKE) | trigger
Instance: c4a-highmem-16 (12 vCPU / 65 GiB) | Linux bench-c4190456325-870-pb5sw 6.12.55+ #1 SMP Sun Feb 1 08:59:41 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 feat/sort-file-groups-by-statistics (790cbce) to c17c87c (merge-base) diff using: clickbench_partitioned
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)

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 feat_sort-file-groups-by-statistics
--------------------
Benchmark tpcds_sf1.json
--------------------
┏━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Query     ┃                                     HEAD ┃      feat_sort-file-groups-by-statistics ┃        Change ┃
┡━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ QQuery 1  │              6.50 / 6.94 ±0.79 / 8.52 ms │              6.59 / 7.07 ±0.75 / 8.57 ms │     no change │
│ QQuery 2  │        146.16 / 148.02 ±1.42 / 150.52 ms │        146.49 / 147.87 ±1.17 / 149.72 ms │     no change │
│ QQuery 3  │        113.90 / 114.81 ±0.69 / 115.79 ms │        113.98 / 114.40 ±0.39 / 114.91 ms │     no change │
│ QQuery 4  │    1249.93 / 1282.60 ±22.98 / 1317.19 ms │    1238.99 / 1273.25 ±21.92 / 1304.05 ms │     no change │
│ QQuery 5  │        171.92 / 173.70 ±1.40 / 175.74 ms │        173.47 / 175.21 ±1.64 / 177.88 ms │     no change │
│ QQuery 6  │       806.49 / 834.71 ±21.92 / 870.00 ms │       816.51 / 840.30 ±30.25 / 899.26 ms │     no change │
│ QQuery 7  │        350.09 / 353.49 ±1.82 / 355.53 ms │        347.34 / 351.08 ±2.08 / 352.88 ms │     no change │
│ QQuery 8  │        114.16 / 115.50 ±1.05 / 117.12 ms │        113.52 / 116.16 ±1.74 / 118.88 ms │     no change │
│ QQuery 9  │       100.35 / 110.37 ±10.66 / 131.07 ms │        100.89 / 103.53 ±2.50 / 107.24 ms │ +1.07x faster │
│ QQuery 10 │        105.79 / 106.75 ±1.14 / 108.82 ms │        106.03 / 107.65 ±1.10 / 109.04 ms │     no change │
│ QQuery 11 │        858.46 / 864.88 ±6.53 / 874.03 ms │       865.87 / 878.38 ±10.61 / 894.65 ms │     no change │
│ QQuery 12 │           44.19 / 45.78 ±1.17 / 47.83 ms │           43.75 / 46.07 ±1.34 / 47.67 ms │     no change │
│ QQuery 13 │        394.73 / 397.54 ±2.75 / 402.63 ms │        392.00 / 398.62 ±3.54 / 402.61 ms │     no change │
│ QQuery 14 │     1029.14 / 1029.78 ±0.52 / 1030.57 ms │    1014.36 / 1035.89 ±11.47 / 1047.03 ms │     no change │
│ QQuery 15 │           15.37 / 17.13 ±1.28 / 18.83 ms │           15.31 / 15.66 ±0.25 / 15.92 ms │ +1.09x faster │
│ QQuery 16 │              7.09 / 7.62 ±0.90 / 9.41 ms │              7.49 / 8.10 ±0.71 / 9.03 ms │  1.06x slower │
│ QQuery 17 │        235.36 / 238.48 ±2.22 / 242.21 ms │        237.30 / 238.66 ±2.06 / 242.75 ms │     no change │
│ QQuery 18 │        126.07 / 127.97 ±1.32 / 130.03 ms │        127.92 / 129.09 ±0.99 / 130.45 ms │     no change │
│ QQuery 19 │        154.25 / 156.05 ±1.32 / 157.14 ms │        157.04 / 158.81 ±1.61 / 161.50 ms │     no change │
│ QQuery 20 │           13.25 / 13.82 ±0.40 / 14.48 ms │           13.99 / 14.61 ±0.59 / 15.65 ms │  1.06x slower │
│ QQuery 21 │           19.14 / 19.21 ±0.04 / 19.27 ms │           19.50 / 20.04 ±0.59 / 21.16 ms │     no change │
│ QQuery 22 │        483.65 / 487.66 ±3.40 / 493.78 ms │        486.09 / 490.05 ±2.32 / 492.61 ms │     no change │
│ QQuery 23 │        871.97 / 883.00 ±9.46 / 896.61 ms │        888.62 / 900.25 ±6.75 / 909.13 ms │     no change │
│ QQuery 24 │        387.76 / 389.79 ±1.92 / 393.44 ms │        393.07 / 395.89 ±2.47 / 399.64 ms │     no change │
│ QQuery 25 │        348.74 / 350.36 ±2.19 / 354.71 ms │        349.46 / 350.06 ±0.44 / 350.66 ms │     no change │
│ QQuery 26 │           79.20 / 83.49 ±2.47 / 85.73 ms │           81.37 / 82.59 ±0.77 / 83.37 ms │     no change │
│ QQuery 27 │              7.09 / 7.59 ±0.53 / 8.32 ms │              6.84 / 7.34 ±0.40 / 8.03 ms │     no change │
│ QQuery 28 │        147.52 / 148.74 ±1.09 / 150.33 ms │        148.64 / 150.25 ±1.29 / 151.71 ms │     no change │
│ QQuery 29 │        292.21 / 293.97 ±1.27 / 295.44 ms │        292.52 / 293.93 ±1.38 / 296.20 ms │     no change │
│ QQuery 30 │           44.63 / 46.81 ±1.28 / 48.34 ms │           43.82 / 45.29 ±0.98 / 46.19 ms │     no change │
│ QQuery 31 │        166.98 / 170.69 ±1.97 / 172.65 ms │        171.55 / 172.68 ±1.21 / 174.45 ms │     no change │
│ QQuery 32 │           55.64 / 56.64 ±0.81 / 57.91 ms │          57.19 / 65.89 ±15.82 / 97.52 ms │  1.16x slower │
│ QQuery 33 │        139.45 / 142.23 ±1.67 / 143.93 ms │        141.17 / 143.84 ±2.11 / 147.16 ms │     no change │
│ QQuery 34 │              6.98 / 7.28 ±0.37 / 7.88 ms │              6.90 / 7.19 ±0.32 / 7.80 ms │     no change │
│ QQuery 35 │        107.86 / 108.69 ±0.58 / 109.50 ms │        106.50 / 109.29 ±2.24 / 111.56 ms │     no change │
│ QQuery 36 │              6.34 / 6.50 ±0.17 / 6.82 ms │              6.42 / 6.67 ±0.28 / 7.02 ms │     no change │
│ QQuery 37 │              8.27 / 8.85 ±0.45 / 9.26 ms │             8.62 / 9.01 ±0.51 / 10.01 ms │     no change │
│ QQuery 38 │           84.76 / 88.36 ±2.51 / 91.52 ms │           83.12 / 88.10 ±4.23 / 95.88 ms │     no change │
│ QQuery 39 │        124.50 / 127.75 ±1.77 / 129.52 ms │        120.02 / 125.28 ±3.52 / 129.45 ms │     no change │
│ QQuery 40 │        109.05 / 118.97 ±8.15 / 132.74 ms │        116.08 / 119.92 ±5.15 / 129.43 ms │     no change │
│ QQuery 41 │           14.46 / 16.22 ±1.08 / 17.51 ms │           14.68 / 14.89 ±0.26 / 15.38 ms │ +1.09x faster │
│ QQuery 42 │        105.75 / 107.50 ±1.70 / 110.68 ms │        108.38 / 110.63 ±1.46 / 112.82 ms │     no change │
│ QQuery 43 │              6.00 / 6.15 ±0.14 / 6.39 ms │              5.79 / 5.99 ±0.22 / 6.41 ms │     no change │
│ QQuery 44 │           11.47 / 11.72 ±0.15 / 11.90 ms │           11.14 / 11.66 ±0.32 / 12.02 ms │     no change │
│ QQuery 45 │           52.01 / 53.51 ±1.28 / 54.94 ms │           51.79 / 53.99 ±1.85 / 57.42 ms │     no change │
│ QQuery 46 │              8.31 / 8.62 ±0.25 / 8.88 ms │              8.13 / 8.46 ±0.37 / 9.18 ms │     no change │
│ QQuery 47 │       667.46 / 684.52 ±10.77 / 696.74 ms │        692.60 / 697.24 ±4.94 / 706.50 ms │     no change │
│ QQuery 48 │        286.92 / 289.84 ±2.29 / 292.27 ms │        281.70 / 286.26 ±3.76 / 291.11 ms │     no change │
│ QQuery 49 │        251.54 / 254.30 ±2.26 / 258.04 ms │        253.40 / 256.70 ±1.73 / 258.52 ms │     no change │
│ QQuery 50 │        230.39 / 234.50 ±2.80 / 237.86 ms │        228.90 / 233.51 ±3.09 / 238.55 ms │     no change │
│ QQuery 51 │        183.07 / 184.53 ±1.08 / 186.33 ms │        182.16 / 184.70 ±1.85 / 186.52 ms │     no change │
│ QQuery 52 │        105.77 / 106.79 ±1.18 / 108.65 ms │        107.06 / 109.27 ±2.28 / 113.42 ms │     no change │
│ QQuery 53 │        101.33 / 102.79 ±0.88 / 103.99 ms │        102.04 / 102.79 ±0.65 / 103.82 ms │     no change │
│ QQuery 54 │        143.40 / 144.91 ±0.85 / 145.72 ms │        144.57 / 147.46 ±1.63 / 149.37 ms │     no change │
│ QQuery 55 │        105.70 / 107.59 ±1.94 / 110.61 ms │        109.27 / 110.53 ±1.22 / 112.85 ms │     no change │
│ QQuery 56 │        139.47 / 140.73 ±1.15 / 142.58 ms │        140.98 / 142.44 ±1.02 / 144.15 ms │     no change │
│ QQuery 57 │        172.48 / 175.26 ±2.30 / 177.84 ms │        173.57 / 175.83 ±1.43 / 178.07 ms │     no change │
│ QQuery 58 │        296.75 / 302.60 ±4.00 / 307.96 ms │        290.37 / 299.75 ±5.58 / 305.05 ms │     no change │
│ QQuery 59 │        198.66 / 200.99 ±1.97 / 203.72 ms │        197.79 / 201.09 ±1.97 / 203.67 ms │     no change │
│ QQuery 60 │        141.67 / 143.14 ±1.37 / 145.67 ms │        144.71 / 145.71 ±1.24 / 148.16 ms │     no change │
│ QQuery 61 │           13.07 / 13.28 ±0.22 / 13.67 ms │           12.81 / 13.20 ±0.23 / 13.46 ms │     no change │
│ QQuery 62 │       871.82 / 910.87 ±35.28 / 976.82 ms │       894.17 / 908.93 ±10.60 / 921.94 ms │     no change │
│ QQuery 63 │        102.37 / 104.90 ±2.51 / 109.64 ms │        102.42 / 105.41 ±2.11 / 108.26 ms │     no change │
│ QQuery 64 │        687.05 / 695.87 ±5.17 / 702.82 ms │        694.85 / 698.90 ±3.21 / 704.37 ms │     no change │
│ QQuery 65 │        246.07 / 248.86 ±1.73 / 250.98 ms │        245.99 / 250.03 ±4.09 / 256.82 ms │     no change │
│ QQuery 66 │       226.56 / 246.96 ±14.84 / 271.41 ms │        240.68 / 255.87 ±8.70 / 266.15 ms │     no change │
│ QQuery 67 │        311.99 / 319.73 ±9.78 / 337.67 ms │        311.06 / 317.00 ±4.74 / 325.02 ms │     no change │
│ QQuery 68 │            9.24 / 10.07 ±0.57 / 10.71 ms │            9.54 / 10.72 ±0.79 / 11.94 ms │  1.06x slower │
│ QQuery 69 │        100.66 / 102.61 ±2.12 / 106.28 ms │        103.78 / 104.71 ±0.57 / 105.49 ms │     no change │
│ QQuery 70 │        334.10 / 342.76 ±5.04 / 347.71 ms │       330.33 / 343.71 ±12.85 / 366.29 ms │     no change │
│ QQuery 71 │        132.59 / 135.58 ±3.19 / 141.44 ms │        134.26 / 135.38 ±0.81 / 136.74 ms │     no change │
│ QQuery 72 │        707.45 / 713.60 ±3.44 / 717.83 ms │       685.64 / 702.52 ±17.14 / 734.55 ms │     no change │
│ QQuery 73 │              6.77 / 7.95 ±1.02 / 9.30 ms │             6.59 / 8.11 ±1.80 / 11.62 ms │     no change │
│ QQuery 74 │       545.30 / 556.90 ±12.96 / 581.11 ms │        538.36 / 547.66 ±6.56 / 557.32 ms │     no change │
│ QQuery 75 │        273.60 / 277.09 ±2.10 / 279.59 ms │        273.86 / 276.49 ±2.12 / 279.03 ms │     no change │
│ QQuery 76 │        130.56 / 132.84 ±1.95 / 135.73 ms │        131.68 / 132.38 ±0.48 / 132.97 ms │     no change │
│ QQuery 77 │        188.97 / 190.87 ±1.81 / 193.75 ms │        187.06 / 190.12 ±1.98 / 192.10 ms │     no change │
│ QQuery 78 │        347.71 / 350.19 ±2.54 / 354.71 ms │        347.40 / 351.52 ±3.86 / 358.26 ms │     no change │
│ QQuery 79 │        229.85 / 231.61 ±1.65 / 234.26 ms │        231.36 / 235.22 ±3.01 / 237.94 ms │     no change │
│ QQuery 80 │        324.42 / 327.96 ±2.23 / 331.12 ms │        326.72 / 330.94 ±2.83 / 334.94 ms │     no change │
│ QQuery 81 │           26.06 / 27.15 ±0.98 / 28.91 ms │           26.35 / 26.82 ±0.59 / 27.99 ms │     no change │
│ QQuery 82 │        197.96 / 200.99 ±2.01 / 203.29 ms │        195.90 / 197.71 ±1.41 / 199.73 ms │     no change │
│ QQuery 83 │           39.66 / 41.43 ±1.87 / 44.86 ms │           39.04 / 39.99 ±0.93 / 41.75 ms │     no change │
│ QQuery 84 │           47.97 / 48.99 ±1.26 / 51.42 ms │           47.74 / 48.91 ±0.97 / 50.64 ms │     no change │
│ QQuery 85 │        145.81 / 148.47 ±2.11 / 151.69 ms │        146.75 / 148.00 ±1.05 / 149.87 ms │     no change │
│ QQuery 86 │           37.82 / 39.02 ±0.76 / 39.83 ms │           38.45 / 39.56 ±0.74 / 40.43 ms │     no change │
│ QQuery 87 │           84.74 / 88.14 ±2.81 / 92.57 ms │           86.14 / 89.86 ±3.67 / 96.44 ms │     no change │
│ QQuery 88 │         99.03 / 100.51 ±1.22 / 102.55 ms │        100.51 / 101.59 ±0.66 / 102.52 ms │     no change │
│ QQuery 89 │        117.12 / 118.20 ±0.70 / 119.24 ms │        117.15 / 119.19 ±1.32 / 121.10 ms │     no change │
│ QQuery 90 │           23.07 / 24.20 ±0.70 / 25.28 ms │           23.46 / 23.79 ±0.27 / 24.21 ms │     no change │
│ QQuery 91 │           63.35 / 64.58 ±1.21 / 66.17 ms │           62.69 / 64.12 ±1.75 / 67.15 ms │     no change │
│ QQuery 92 │           56.57 / 57.20 ±0.56 / 58.19 ms │           56.76 / 57.46 ±0.44 / 57.97 ms │     no change │
│ QQuery 93 │        189.28 / 192.70 ±2.17 / 195.91 ms │        191.70 / 193.00 ±1.03 / 194.46 ms │     no change │
│ QQuery 94 │           58.67 / 60.55 ±1.12 / 61.77 ms │           60.02 / 60.75 ±0.45 / 61.44 ms │     no change │
│ QQuery 95 │        131.07 / 134.04 ±1.91 / 136.99 ms │        134.95 / 135.82 ±0.60 / 136.53 ms │     no change │
│ QQuery 96 │           74.04 / 74.79 ±0.64 / 75.56 ms │           71.27 / 74.57 ±1.75 / 76.42 ms │     no change │
│ QQuery 97 │        130.40 / 131.59 ±1.19 / 133.60 ms │        130.15 / 133.48 ±1.76 / 135.28 ms │     no change │
│ QQuery 98 │        150.55 / 153.74 ±2.30 / 156.68 ms │        153.06 / 154.68 ±1.10 / 156.10 ms │     no change │
│ QQuery 99 │ 10772.73 / 10801.06 ±29.00 / 10847.03 ms │ 10721.29 / 10763.22 ±23.70 / 10784.71 ms │     no change │
└───────────┴──────────────────────────────────────────┴──────────────────────────────────────────┴───────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┓
┃ Benchmark Summary                                  ┃            ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━┩
│ Total Time (HEAD)                                  │ 31396.62ms │
│ Total Time (feat_sort-file-groups-by-statistics)   │ 31434.20ms │
│ Average Time (HEAD)                                │   317.14ms │
│ Average Time (feat_sort-file-groups-by-statistics) │   317.52ms │
│ Queries Faster                                     │          3 │
│ Queries Slower                                     │          4 │
│ Queries with No Change                             │         92 │
│ Queries with Failure                               │          0 │
└────────────────────────────────────────────────────┴────────────┘

Resource Usage

tpcds — base (merge-base)

Metric Value
Wall time 157.3s
Peak memory 5.4 GiB
Avg memory 4.5 GiB
CPU user 257.1s
CPU sys 16.6s
Peak spill 0 B

tpcds — branch

Metric Value
Wall time 157.4s
Peak memory 5.3 GiB
Avg memory 4.5 GiB
CPU user 258.0s
CPU sys 16.9s
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)

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 feat_sort-file-groups-by-statistics
--------------------
Benchmark clickbench_partitioned.json
--------------------
┏━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Query     ┃                                  HEAD ┃    feat_sort-file-groups-by-statistics ┃        Change ┃
┡━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ QQuery 0  │          1.21 / 4.50 ±6.44 / 17.38 ms │           1.20 / 4.39 ±6.29 / 16.97 ms │     no change │
│ QQuery 1  │        14.31 / 14.90 ±0.32 / 15.27 ms │         14.18 / 14.55 ±0.24 / 14.87 ms │     no change │
│ QQuery 2  │        44.46 / 44.95 ±0.30 / 45.33 ms │         43.29 / 43.72 ±0.24 / 43.99 ms │     no change │
│ QQuery 3  │        42.75 / 46.40 ±1.96 / 48.29 ms │         39.94 / 43.53 ±2.77 / 46.71 ms │ +1.07x faster │
│ QQuery 4  │    297.97 / 314.78 ±12.54 / 334.15 ms │      295.14 / 301.67 ±5.38 / 310.99 ms │     no change │
│ QQuery 5  │     353.28 / 355.68 ±2.29 / 359.05 ms │      348.04 / 353.27 ±4.95 / 361.99 ms │     no change │
│ QQuery 6  │           5.25 / 6.54 ±0.78 / 7.46 ms │            4.90 / 6.33 ±1.10 / 8.24 ms │     no change │
│ QQuery 7  │        16.70 / 18.73 ±3.53 / 25.77 ms │         16.62 / 17.28 ±0.68 / 18.46 ms │ +1.08x faster │
│ QQuery 8  │    430.06 / 444.94 ±11.30 / 464.14 ms │      423.13 / 435.00 ±7.88 / 444.16 ms │     no change │
│ QQuery 9  │     647.69 / 658.57 ±6.76 / 668.46 ms │      648.80 / 655.73 ±4.89 / 661.64 ms │     no change │
│ QQuery 10 │        92.20 / 95.68 ±2.26 / 98.87 ms │        93.00 / 96.27 ±3.13 / 101.69 ms │     no change │
│ QQuery 11 │     105.53 / 106.16 ±0.52 / 107.02 ms │      104.46 / 106.09 ±1.37 / 108.40 ms │     no change │
│ QQuery 12 │     348.33 / 354.79 ±5.22 / 361.96 ms │      348.24 / 353.71 ±3.37 / 357.91 ms │     no change │
│ QQuery 13 │    463.18 / 474.38 ±12.96 / 498.61 ms │     466.26 / 487.13 ±13.04 / 499.08 ms │     no change │
│ QQuery 14 │     354.74 / 363.15 ±5.71 / 368.39 ms │      367.49 / 369.80 ±1.52 / 371.84 ms │     no change │
│ QQuery 15 │     357.96 / 376.13 ±9.85 / 386.76 ms │     373.53 / 398.88 ±21.14 / 425.02 ms │  1.06x slower │
│ QQuery 16 │    729.24 / 741.00 ±14.11 / 767.87 ms │     722.52 / 740.86 ±18.61 / 775.17 ms │     no change │
│ QQuery 17 │    720.08 / 758.05 ±28.45 / 799.97 ms │      717.24 / 729.07 ±9.58 / 741.23 ms │     no change │
│ QQuery 18 │ 1440.63 / 1488.92 ±36.98 / 1536.17 ms │  1475.65 / 1502.63 ±35.41 / 1568.93 ms │     no change │
│ QQuery 19 │       35.86 / 45.26 ±16.08 / 77.22 ms │         36.56 / 38.59 ±1.86 / 41.84 ms │ +1.17x faster │
│ QQuery 20 │    720.76 / 739.46 ±19.64 / 771.16 ms │     722.50 / 737.18 ±20.99 / 778.36 ms │     no change │
│ QQuery 21 │     762.87 / 769.18 ±4.88 / 777.77 ms │      765.89 / 768.44 ±2.99 / 773.03 ms │     no change │
│ QQuery 22 │  1132.96 / 1139.30 ±5.66 / 1148.78 ms │   1135.41 / 1144.58 ±4.61 / 1147.52 ms │     no change │
│ QQuery 23 │ 3074.89 / 3093.85 ±12.25 / 3106.97 ms │   3080.24 / 3095.14 ±8.28 / 3105.77 ms │     no change │
│ QQuery 24 │      98.90 / 103.07 ±2.87 / 107.17 ms │       99.79 / 103.56 ±2.40 / 107.16 ms │     no change │
│ QQuery 25 │     140.10 / 141.98 ±1.48 / 144.31 ms │      137.27 / 139.75 ±2.61 / 143.98 ms │     no change │
│ QQuery 26 │      99.12 / 102.69 ±2.58 / 105.21 ms │       98.97 / 101.65 ±1.67 / 103.81 ms │     no change │
│ QQuery 27 │     849.35 / 856.31 ±6.58 / 866.41 ms │      853.46 / 855.70 ±1.83 / 858.67 ms │     no change │
│ QQuery 28 │ 7715.05 / 7772.07 ±34.36 / 7808.87 ms │  7709.32 / 7788.82 ±40.83 / 7824.80 ms │     no change │
│ QQuery 29 │        51.29 / 55.51 ±4.30 / 63.51 ms │         50.55 / 55.26 ±6.06 / 67.22 ms │     no change │
│ QQuery 30 │     367.11 / 372.74 ±3.42 / 377.60 ms │      361.66 / 372.57 ±9.16 / 388.78 ms │     no change │
│ QQuery 31 │    366.04 / 381.84 ±17.92 / 415.68 ms │     359.51 / 381.79 ±14.25 / 403.71 ms │     no change │
│ QQuery 32 │ 1246.30 / 1316.95 ±37.14 / 1348.17 ms │ 1061.12 / 1183.54 ±115.99 / 1337.28 ms │ +1.11x faster │
│ QQuery 33 │ 1493.69 / 1560.93 ±39.38 / 1615.54 ms │  1471.10 / 1487.87 ±10.91 / 1500.29 ms │     no change │
│ QQuery 34 │ 1515.29 / 1565.52 ±41.62 / 1629.69 ms │  1474.09 / 1494.99 ±13.71 / 1512.15 ms │     no change │
│ QQuery 35 │    409.69 / 466.13 ±76.54 / 614.75 ms │      387.72 / 397.78 ±7.34 / 407.37 ms │ +1.17x faster │
│ QQuery 36 │     122.99 / 132.65 ±6.51 / 143.35 ms │      114.93 / 123.71 ±5.19 / 129.55 ms │ +1.07x faster │
│ QQuery 37 │        50.31 / 57.34 ±8.72 / 74.13 ms │         48.13 / 50.67 ±1.48 / 52.45 ms │ +1.13x faster │
│ QQuery 38 │        86.24 / 87.24 ±0.79 / 88.38 ms │         74.38 / 75.86 ±0.85 / 76.97 ms │ +1.15x faster │
│ QQuery 39 │     229.74 / 241.59 ±6.43 / 248.93 ms │      207.89 / 221.85 ±9.36 / 233.07 ms │ +1.09x faster │
│ QQuery 40 │        24.22 / 27.01 ±1.57 / 28.99 ms │         21.47 / 23.72 ±2.06 / 27.28 ms │ +1.14x faster │
│ QQuery 41 │        19.77 / 20.74 ±0.64 / 21.61 ms │         20.07 / 21.78 ±1.21 / 23.83 ms │  1.05x slower │
│ QQuery 42 │        19.98 / 20.37 ±0.26 / 20.65 ms │         19.09 / 19.97 ±0.44 / 20.30 ms │     no change │
└───────────┴───────────────────────────────────────┴────────────────────────────────────────┴───────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┓
┃ Benchmark Summary                                  ┃            ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━┩
│ Total Time (HEAD)                                  │ 27737.97ms │
│ Total Time (feat_sort-file-groups-by-statistics)   │ 27344.66ms │
│ Average Time (HEAD)                                │   645.07ms │
│ Average Time (feat_sort-file-groups-by-statistics) │   635.92ms │
│ Queries Faster                                     │         10 │
│ Queries Slower                                     │          2 │
│ Queries with No Change                             │         31 │
│ Queries with Failure                               │          0 │
└────────────────────────────────────────────────────┴────────────┘

Resource Usage

clickbench_partitioned — base (merge-base)

Metric Value
Wall time 139.2s
Peak memory 38.9 GiB
Avg memory 28.7 GiB
CPU user 1294.1s
CPU sys 108.9s
Peak spill 0 B

clickbench_partitioned — branch

Metric Value
Wall time 137.8s
Peak memory 38.8 GiB
Avg memory 30.0 GiB
CPU user 1292.9s
CPU sys 92.5s
Peak spill 0 B

File an issue against this benchmark runner

@adriangb
Copy link
Copy Markdown
Contributor

adriangb commented Apr 6, 2026

Look good to me 😄!

Let's wait for Andrew to chime in tomorrow w.r.t. the max buffer size.

Copy link
Copy Markdown
Contributor

@alamb alamb left a comment

Choose a reason for hiding this comment

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

Looks great to me -- thank you so much @zhuqi-lucas and @adriangb

new_groups.push(sorted_group);
}

SortedFileGroups {
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.

As a follow on PR it might be nice to figure out how to move some of this code out of FileScanConfig and into some other smaller module (no need to do it in this PR, I am just observing that the FileScanConfig is getting large)

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.

Good point! Created #21433 to track this refactor.

@adriangb
Copy link
Copy Markdown
Contributor

adriangb commented Apr 6, 2026

@alamb wdyt of setting the max buffer so something larger like 1Gi? The point is that even if it hits that limit it will be strictly less memory usage than SortExec. If we set it too small some workloads will be IO starved.

@alamb
Copy link
Copy Markdown
Contributor

alamb commented Apr 6, 2026

@alamb wdyt of setting the max buffer so something larger like 1Gi? The point is that even if it hits that limit it will be strictly less memory usage than SortExec. If we set it too small some workloads will be IO starved.

I think the rationale state in

/// This is strictly less memory than the SortExec it replaces, and only
/// inserted when PushdownSort eliminates a SortExec — no impact on other
/// query plans. BufferExec also integrates with MemoryPool, so it respects
/// the global memory limit and won't cause OOM.

Makes sense to me

If you wanted to be really nice you could make it a config option

@adriangb
Copy link
Copy Markdown
Contributor

adriangb commented Apr 6, 2026

I think this is already a big PR and has been open for a while, I don't want to delay this great work and real world wins. What I propose is that we merge this with the current hardcoded limit and then if you don't mind in a followup adding a config option and bumping the default to 1Gi @zhuqi-lucas

@adriangb adriangb added this pull request to the merge queue Apr 6, 2026
Merged via the queue into apache:main with commit cdfade5 Apr 6, 2026
35 checks passed
@adriangb
Copy link
Copy Markdown
Contributor

adriangb commented Apr 6, 2026

I filed a followup in #21417

@zhuqi-lucas
Copy link
Copy Markdown
Contributor Author

Thanks @adriangb , @alamb and @Dandandan for review!

@alamb
Copy link
Copy Markdown
Contributor

alamb commented Apr 7, 2026

this is an amazing piece of work (several years in the making)

@adriangb
Copy link
Copy Markdown
Contributor

adriangb commented Apr 7, 2026

certainly worthy of a blog post!

github-merge-queue bot pushed a commit that referenced this pull request Apr 7, 2026
#21426)

## Which issue does this PR close?

Closes #21417

## Rationale for this change

#21182 introduced `BufferExec` between `SortPreservingMergeExec` and
`DataSourceExec` when sort elimination removes a `SortExec`. The buffer
capacity was hardcoded to 64MB, which can cause I/O stalls for wide-row
full scans.

## What changes are included in this PR?

- Add `datafusion.execution.sort_pushdown_buffer_capacity` config option
(default 1GB)
- Replace hardcoded `BUFFER_CAPACITY_AFTER_SORT_ELIMINATION` constant
with the config value
- Update SLT test expectations for new default capacity

## How are these changes justified?

**Why 1GB default:**
- This is a maximum, not pre-allocated — actual usage is bounded by
partition data size
- Strictly less memory than the `SortExec` it replaces (which buffers
entire partition)
- `BufferExec` integrates with `MemoryPool`, so global memory limits are
respected
- 64MB was too small for wide-row scans (16-column TPC-H `SELECT *`
queries showed I/O stalls)

**Why configurable:**
- Different workloads have different optimal buffer sizes
- Users with memory-constrained environments can reduce it
- Users with wide tables or large row groups can increase it

## Are these changes tested?

- Existing SLT Test G verifies `BufferExec` appears in plan with correct
capacity
- Config integration tested via existing config framework

## Are there any user-facing changes?

New config option: `datafusion.execution.sort_pushdown_buffer_capacity`
(default: 1GB)
@zhuqi-lucas
Copy link
Copy Markdown
Contributor Author

Good idea @alamb @adriangb , i will try to write a blog after remaining #21317 done.

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

Labels

core Core DataFusion crate datasource Changes to the datasource crate optimizer Optimizer rules physical-plan Changes to the physical-plan crate sqllogictest SQL Logic Tests (.slt)

Projects

None yet

7 participants