Skip to content

feat: add a sorted TPC-H benchmark dataset - #646

Merged
gabotechs merged 4 commits into
datafusion-contrib:mainfrom
shinzoxD:feat-tpch-sorted-632
Aug 24, 2026
Merged

feat: add a sorted TPC-H benchmark dataset#646
gabotechs merged 4 commits into
datafusion-contrib:mainfrom
shinzoxD:feat-tpch-sorted-632

Conversation

@shinzoxD

@shinzoxD shinzoxD commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a deterministic tpch/sorted_sf1 benchmark dataset variant so physical data ordering is a controlled dimension while keeping the standard TPC-H query workload. Part of #629, closes #632.

Uses the same tpchgen generators and Arrow writer as unsorted TPC-H, recording table-specific Parquet sorting_columns metadata in one pass (prepare-tpch --sorted).

Sort keys

Table Sort columns
region r_regionkey
nation n_nationkey
customer c_custkey
supplier s_suppkey
part p_partkey
partsupp ps_partkey
orders o_orderkey
lineitem l_orderkey, l_linenumber

partsupp records only ps_partkey because ps_suppkey wraps within each part.

Data is written to testdata/tpch/sorted_sf<scale-factor>/.

# Default SF1, 16 files per table
./benchmarks/gen-tpch-sorted.sh

# Tiny smoke-scale dataset
SCALE_FACTOR=0.01 ./benchmarks/gen-tpch-sorted.sh

WORKERS=8 ./benchmarks/run.sh --threads 2 --dataset tpch/sorted_sf1

Queries stay in testdata/tpch/queries. run_local extracts the tpch suite from tpch/sorted_sf1, so queries_for_dataset is unchanged. register_tables is unchanged.

Implementation

  • benchmarks/src/datasets/tpch.rs: optional sorting_columns on the existing writer
  • prepare-tpch --sorted instead of a separate async rewrite command
  • benchmarks/gen-tpch-sorted.sh writes testdata/tpch/sorted_sf<scale-factor>

SF1 was not generated in this PR (heavy, and blocked here by the OpenSSL build). Use SCALE_FACTOR=0.01 to smoke the path, then ./benchmarks/gen-tpch-sorted.sh for SF1.

Copilot AI lite review requested due to automatic review settings August 15, 2026 19:57

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@shinzoxD

Copy link
Copy Markdown
Contributor Author

CI was failing while compiling datafusion-distributed-benchmarks:

error[E0382]: use of moved value: `df`
--> benchmarks/src/datasets/tpch_sorted.rs:163:10
    let mut stream = df.execute_stream().await?;
    drop(df);  // used after move

DataFrame::execute_stream takes self, so the follow-up drop(df) was a use-after-move. Clippy also treated the unused std::sync::Arc import as an error under -D warnings.

Fixed in 077e224: drop the finished stream (and session) so file handles are released before the table directory is replaced, and move the unused import plus test-only sort helpers into the test module.

Comment thread benchmarks/src/datasets/tpch_sorted.rs Outdated
parts: usize,
) -> Result<(), Box<dyn std::error::Error>> {
tpch::generate_tpch_data(data_dir, sf, parts)?;
rewrite_tables_globally_sorted(data_dir).await

@gabotechs gabotechs Aug 17, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This extra read/sort/rewrite pass should not be needed. It should be enough to implement the sorted layout as a small variant of the existing datasets/tpch.rs: reuse the same tpchgen generators and Arrow writer, passing table-specific SortingColumns to WriterProperties when each Parquet file is created. I verified that the pinned tpchgen emits lineitem ordered by (l_orderkey, l_linenumber) and orders/customer/supplier/part by their generated keys. For partsupp, only ps_partkey is naturally ordered because ps_suppkey wraps, so declare only that prefix. The existing prepare-tpch command can take a sorted-variant flag instead of adding this rewrite implementation and a separate asynchronous preparation path.

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.

Implemented in 26040dc. Sorted TPC-H now reuses the existing tpchgen generators and Arrow writer in datasets/tpch.rs, writing table-specific SortingColumn metadata in one pass. partsupp records only ps_partkey. --sorted is a flag on prepare-tpch; the rewrite path and prepare-tpch-sorted command are gone.

Comment thread benchmarks/src/run.rs Outdated
fn queries_for_dataset(dataset: &str) -> Result<Vec<(String, String)>, DataFusionError> {
match dataset {
"tpch" => tpch::get_queries()
"tpch" | "tpch-sorted" => tpch::get_queries()

@gabotechs gabotechs Aug 17, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We can model this as the TPC-H variant tpch/sorted_sf1, rather than a new top-level tpch-sorted dataset. run_local already extracts tpch as the suite before calling queries_for_dataset, and dataset_path resolves the suffix to testdata/tpch/sorted_sf1, so the existing "tpch" branch works unchanged. The generation script should write to that location and this additional match arm can be removed.

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.

Implemented in 26040dc. The variant is now tpch/sorted_sf1, resolved to testdata/tpch/sorted_sf1. queries_for_dataset keeps the existing "tpch" branch; gen-tpch-sorted.sh writes to that path.

Comment thread benchmarks/src/datasets/tpch_sorted.rs Outdated
.count())
}

#[cfg(test)]

@gabotechs gabotechs Aug 17, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

We can remove this test module, including its test-only helpers and imports. This is benchmark data-preparation code rather than production code, and these tests add roughly 240 lines of maintenance overhead to what should be a small Parquet-metadata variant of the existing TPC-H generator.

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.

Implemented in 26040dc. Removed the test module, helpers, and tpch_sorted.rs.

@shinzoxD
shinzoxD force-pushed the feat-tpch-sorted-632 branch from 077e224 to 26040dc Compare August 19, 2026 19:11
Comment thread benchmarks/gen-tpch-sorted.sh Outdated

set -e

SCALE_FACTOR=${SCALE_FACTOR:-1}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

It should be fine to use reuse the existing gen-tpch.sh script with a simple SORTED={true|false} flag populated by an env variable.

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.

Implemented in f31267d. Sorted generation is now SORTED=true ./gen-tpch.sh; gen-tpch-sorted.sh is removed. Default remains unsorted (SORTED=false).

Add a deterministic tpch-sorted variant whose Parquet tables are globally
sorted by documented TPC-H primary keys. Generation follows the existing
TPC-H scale-factor model and writes testdata/tpch-sorted/sf<scale-factor>.

Fixes datafusion-contrib#632
DataFrame::execute_stream takes self, so drop(df) after starting the
stream is a use-after-move. Drop the finished stream instead so
Windows file locks are released before the table directory is
replaced. Move unused Arc and test-only sort helpers into the test
module so clippy -D warnings stays clean.
Reuse the existing tpchgen generators and Arrow writer, recording table-specific Parquet sorting_columns in one pass. Model the dataset as the TPC-H variant tpch/sorted_sf1, fold --sorted into prepare-tpch, and drop the rewrite path and its tests.
Fold the sorted variant into gen-tpch.sh so SORTED=true writes
tpch/sorted_sf<scale-factor> with --sorted, and default SORTED=false
keeps the existing unsorted path.
@shinzoxD
shinzoxD force-pushed the feat-tpch-sorted-632 branch from 26040dc to f31267d Compare August 24, 2026 14:46

@gabotechs gabotechs left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This one looks good. Thanks @shinzoxD!

@gabotechs
gabotechs merged commit 9cc7c01 into datafusion-contrib:main Aug 24, 2026
31 checks passed
alexanderbianchi pushed a commit to alexanderbianchi/datafusion-distributed that referenced this pull request Aug 24, 2026
## Summary

Adds a deterministic `tpch/sorted_sf1` benchmark dataset variant so
physical data ordering is a controlled dimension while keeping the
standard TPC-H query workload. Part of datafusion-contrib#629, closes datafusion-contrib#632.

Uses the same `tpchgen` generators and Arrow writer as unsorted TPC-H,
recording table-specific Parquet `sorting_columns` metadata in one pass
(`prepare-tpch --sorted`).

## Sort keys

| Table | Sort columns |
| --- | --- |
| region | `r_regionkey` |
| nation | `n_nationkey` |
| customer | `c_custkey` |
| supplier | `s_suppkey` |
| part | `p_partkey` |
| partsupp | `ps_partkey` |
| orders | `o_orderkey` |
| lineitem | `l_orderkey`, `l_linenumber` |

`partsupp` records only `ps_partkey` because `ps_suppkey` wraps within
each part.

Data is written to `testdata/tpch/sorted_sf<scale-factor>/`.

```bash
# Default SF1, 16 files per table
./benchmarks/gen-tpch-sorted.sh

# Tiny smoke-scale dataset
SCALE_FACTOR=0.01 ./benchmarks/gen-tpch-sorted.sh

WORKERS=8 ./benchmarks/run.sh --threads 2 --dataset tpch/sorted_sf1
```

Queries stay in `testdata/tpch/queries`. `run_local` extracts the `tpch`
suite from `tpch/sorted_sf1`, so `queries_for_dataset` is unchanged.
`register_tables` is unchanged.

## Implementation

- `benchmarks/src/datasets/tpch.rs`: optional `sorting_columns` on the
existing writer
- `prepare-tpch --sorted` instead of a separate async rewrite command
- `benchmarks/gen-tpch-sorted.sh` writes
`testdata/tpch/sorted_sf<scale-factor>`

SF1 was not generated in this PR (heavy, and blocked here by the OpenSSL
build). Use `SCALE_FACTOR=0.01` to smoke the path, then
`./benchmarks/gen-tpch-sorted.sh` for SF1.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Benchmark datasets] Add a sorted TPC-H benchmark dataset

3 participants