Skip to content

Commit 1c419e5

Browse files
authored
Own SQL benchmark suite (#8719)
Testing SQL queries' correctness is done in vortex-sqllogictest, but we also want to test relative performance of queries not covered in existing benchmarks. One example is aggregation with filter which should be much more performant once we use zone maps statistics, but this type of query isn't present is existing benchmarks. This PR introduces a new query-per-file dataset and support for running it in CI Signed-off-by: Mikhail Kot <mikhail@spiraldb.com>
1 parent d54f70d commit 1c419e5

11 files changed

Lines changed: 294 additions & 1 deletion

File tree

.github/workflows/bench.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,3 +171,31 @@ jobs:
171171
secrets: inherit
172172
with:
173173
mode: "develop"
174+
175+
sql-vortex:
176+
uses: ./.github/workflows/sql-benchmarks.yml
177+
secrets: inherit
178+
with:
179+
mode: "develop"
180+
benchmark_matrix: |
181+
[
182+
{
183+
"id": "vortex-queries",
184+
"subcommand": "vortex",
185+
"name": "Vortex queries",
186+
"data_formats": ["parquet", "vortex"],
187+
"pr_targets": [
188+
{"engine": "datafusion", "format": "parquet"},
189+
{"engine": "datafusion", "format": "vortex"},
190+
{"engine": "duckdb", "format": "parquet"},
191+
{"engine": "duckdb", "format": "vortex"}
192+
],
193+
"develop_targets": [
194+
{"engine": "datafusion", "format": "parquet"},
195+
{"engine": "datafusion", "format": "vortex"},
196+
{"engine": "duckdb", "format": "parquet"},
197+
{"engine": "duckdb", "format": "vortex"}
198+
],
199+
"iterations": "100"
200+
}
201+
]
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Run Vortex SQL benchmark on every commit in a PR.
2+
# This is not gated behind action/benchmark-sql
3+
4+
name: PR Vortex Query Benchmark
5+
6+
concurrency:
7+
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
8+
cancel-in-progress: false
9+
10+
on:
11+
pull_request:
12+
types: [opened, synchronize, reopened]
13+
branches: ["develop"]
14+
15+
permissions:
16+
contents: read
17+
pull-requests: write
18+
id-token: write
19+
20+
jobs:
21+
sql:
22+
uses: ./.github/workflows/sql-benchmarks.yml
23+
secrets: inherit
24+
with:
25+
mode: "pr"
26+
benchmark_matrix: |
27+
[
28+
{
29+
"id": "vortex-queries",
30+
"subcommand": "vortex",
31+
"name": "Vortex queries",
32+
"data_formats": ["parquet", "vortex"],
33+
"pr_targets": [
34+
{"engine": "datafusion", "format": "parquet"},
35+
{"engine": "datafusion", "format": "vortex"},
36+
{"engine": "duckdb", "format": "parquet"},
37+
{"engine": "duckdb", "format": "vortex"}
38+
],
39+
"develop_targets": [
40+
{"engine": "datafusion", "format": "parquet"},
41+
{"engine": "datafusion", "format": "vortex"},
42+
{"engine": "duckdb", "format": "parquet"},
43+
{"engine": "duckdb", "format": "vortex"}
44+
],
45+
"iterations": "100"
46+
}
47+
]

bench-orchestrator/bench_orchestrator/config.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ class Benchmark(Enum):
5454
PUBLIC_BI = "public-bi"
5555
STATPOPGEN = "statpopgen"
5656
SPATIALBENCH = "spatialbench"
57+
VORTEX_QUERIES = "vortex"
5758

5859

5960
# Engine to supported formats mapping.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
-- As this aggregation has a filter, Vortex has to use a linear scan. Once stats
2+
-- are propagated to arrays, this should use zone maps to aggregate instead of
3+
-- decoding and processing each row.
4+
SELECT sum(col) FROM test WHERE col2 > 0 AND col2 < 1000;

vortex-bench/sql/vortex/1_sum.sql

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
-- When Footer changes land, vortex-duckdb should populate statistics from
2+
-- Footer without loading and decoding the data.
3+
SELECT sum(col) FROM test;

vortex-bench/sql/vortex/init.sql

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
-- Script that prepares Parquet data for our SQL microbenchmarks.
2+
3+
COPY (
4+
SELECT
5+
i % 1000 AS col,
6+
(i * 2654435761) % 100000 AS col2
7+
FROM range(25000000) t(i)
8+
) TO 'test.parquet' (FORMAT parquet);

vortex-bench/src/datasets/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ pub enum BenchmarkDataset {
8181
Fineweb,
8282
#[serde(rename = "gharchive")]
8383
GhArchive,
84+
#[serde(rename = "vortex")]
85+
VortexQueries,
8486
}
8587

8688
impl BenchmarkDataset {
@@ -97,6 +99,7 @@ impl BenchmarkDataset {
9799
BenchmarkDataset::PolarSignals { .. } => "polarsignals",
98100
BenchmarkDataset::Fineweb => "fineweb",
99101
BenchmarkDataset::GhArchive => "gharchive",
102+
BenchmarkDataset::VortexQueries => "vortex",
100103
}
101104
}
102105
}
@@ -122,6 +125,7 @@ impl Display for BenchmarkDataset {
122125
}
123126
BenchmarkDataset::Fineweb => write!(f, "fineweb"),
124127
BenchmarkDataset::GhArchive => write!(f, "gharchive"),
128+
BenchmarkDataset::VortexQueries => write!(f, "vortex"),
125129
}
126130
}
127131
}
@@ -179,6 +183,8 @@ impl BenchmarkDataset {
179183
BenchmarkDataset::PolarSignals { .. } => &["stacktraces"],
180184
BenchmarkDataset::Fineweb => &["fineweb"],
181185
BenchmarkDataset::GhArchive => &["events"],
186+
// See VortexBenchmark::table_specs
187+
BenchmarkDataset::VortexQueries => &[],
182188
}
183189
}
184190
}

vortex-bench/src/lib.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ use vortex::file::WriteStrategyBuilder;
3636
use vortex::utils::aliases::hash_map::HashMap;
3737

3838
use crate::spatialbench::SpatialBenchBenchmark;
39+
use crate::vortex_queries::VortexBenchmark;
3940

4041
pub mod appian;
4142
pub mod benchmark;
@@ -61,6 +62,7 @@ pub mod tpch;
6162
pub mod utils;
6263
pub mod v3;
6364
pub mod vector_dataset;
65+
pub mod vortex_queries;
6466

6567
pub use benchmark::Benchmark;
6668
pub use benchmark::TableSpec;
@@ -281,6 +283,8 @@ pub enum BenchmarkArg {
281283
PublicBi,
282284
#[clap(name = "spatialbench")]
283285
SpatialBench,
286+
#[clap(name = "vortex")]
287+
VortexQueries,
284288
}
285289

286290
/// Default scale factor for TPC-related benchmarks
@@ -353,6 +357,13 @@ pub fn create_benchmark(b: BenchmarkArg, opts: &Opts) -> anyhow::Result<Box<dyn
353357
let benchmark = SpatialBenchBenchmark::new(scale_factor.to_string(), remote_data_dir)?;
354358
Ok(Box::new(benchmark) as _)
355359
}
360+
BenchmarkArg::VortexQueries => {
361+
let mut benchmark = VortexBenchmark::new()?;
362+
if let Some(query) = opts.get("query") {
363+
benchmark = benchmark.with_query(query)?;
364+
}
365+
Ok(Box::new(benchmark) as _)
366+
}
356367
}
357368
}
358369

vortex-bench/src/utils/file.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,12 @@ pub trait IdempotentPath {
5656
fn to_data_path(&self) -> PathBuf;
5757
}
5858

59+
pub fn bench_dir() -> PathBuf {
60+
workspace_root().join("vortex-bench")
61+
}
62+
5963
pub fn data_dir() -> PathBuf {
60-
workspace_root().join("vortex-bench").join("data")
64+
bench_dir().join("data")
6165
}
6266

6367
/// Find the workspace's root by looking for Cargo's lock file

vortex-bench/src/v3.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,7 @@ fn canonical_tpc_scale_factor(scale_factor: &str) -> String {
296296
/// | `Appian` | `appian` | `None` | `None` | Static dataset; no scale factor. |
297297
/// | `PublicBi { name }` | `public-bi` | dataset name (e.g. `cms-provider`) | `None` | Sub-dataset name lives in `dataset_variant`. |
298298
/// | `SpatialBench { scale_factor }` | `spatialbench` | `None` | SF as string | Same canonicalization as TPC-H; no historical v2 records to merge with. |
299+
/// | `VortexQueries` | `vortex` | `None` | `None` | Own microbenchmarks |
299300
pub fn benchmark_dataset_dims(d: &BenchmarkDataset) -> (String, Option<String>, Option<String>) {
300301
match d {
301302
BenchmarkDataset::TpcH { scale_factor } => (
@@ -331,6 +332,7 @@ pub fn benchmark_dataset_dims(d: &BenchmarkDataset) -> (String, Option<String>,
331332
BenchmarkDataset::Fineweb => ("fineweb".to_string(), None, None),
332333
BenchmarkDataset::GhArchive => ("gharchive".to_string(), None, None),
333334
BenchmarkDataset::Appian => ("appian".to_string(), None, None),
335+
BenchmarkDataset::VortexQueries => ("vortex".to_string(), None, None),
334336
}
335337
}
336338

0 commit comments

Comments
 (0)