This is an automated email from the ASF dual-hosted git repository. github-merge-queue[bot] pushed a commit to branch gh-readonly-queue/main/pr-24976-9f21155c48faac3f1658853ad6a55bd314a322ed in repository https://gitbox.apache.org/repos/asf/datafusion.git
commit 790b110df7e02ccfdcf152a49e18d87622aa982d Author: Adrian Garcia Badaracco <[email protected]> AuthorDate: Wed Sep 9 12:28:00 2026 +0000 bench(predicate_eval): add expensive-first and wide-column shapes (#25032) ## Which issue does this PR close? - Part of #22883 - Related to #11262 - Prequel split out of #22698: these are the benchmark-suite additions from that PR, carried on their own so they can land (and be run) independently of the adaptive-filter work. ## Rationale for this change The `predicate_eval` suite (the conjunctive-filter microbenchmarks added for adaptive predicate ordering in #11262) was missing a few shapes that distinguish evaluation strategies for AND chains, and it had no result checking at all: 1. **An expensive-selective conjunct written *before* a cheap-unselective one.** The suite already had the reverse (`costsel` q03: cheap `c0 < 90` at ~90% first, expensive `regexp_like(s, 'rare')` at ~0.1% second). Without the mirror shape there is no case in the suite where the as-written order is already the optimal one, so the suite cannot tell "reordered well" apart from "reordered at all". It also exercises a distinct code path: measuring a *cheap* conjunct on the small survivor batch left after pre-selection by an expensive one, rather than measuring an expensive conjunct on a full batch. 2. **A many-column table.** Every existing `cardinality` query runs over the 16-column `ints` dataset, so the cost of materializing a filtered batch per level is small and roughly constant across the suite. Re-running the k = 8 predicate over a 64-column table separates the cost of *evaluating* the conjuncts from the cost of *filtering the batch* at each level, which is what per-level batch filtering actually pays for on wide inputs. 3. **No result validation.** The suite's template had no `result` directive, so `--result-mode validate` verified nothing on it. A reordering under test must not change *which* rows survive the filter, and every query here is a `count(*)` whose value is fixed by the generated data — a checked-in expected count is therefore a free correctness check on top of the timing. 4. **Nullable conjuncts.** Every predicate in the suite was non-nullable, so the suite never exercised the one case where writing the selective conjunct first buys nothing: `BinaryExpr`'s AND pre-selection bails out when the left-hand boolean array contains any NULL. 5. **Drift that a warm-up cannot absorb.** The existing `drift` dataset flipped which conjunct is selective late enough that a one-shot warm-up already lands on the post-flip order and is right for most of the scan. There was no shape where a decide-once strategy is wrong for a large part of the scan, and none at all where the *right* order differs between concurrently running partitions rather than over time. ## What changes are included in this PR? Everything is under `benchmarks/` (plus the suite's own docs); there are no Rust changes, and the suite discovers new `.benchmark` files automatically. - **Result validation.** The shared template gains `result sql_benchmarks/predicate_eval/results/${NAME}.csv`, and every benchmark's expected `count(*)` is checked in under `predicate_eval/results/`, so `--result-mode validate` now checks that a reordering under test still returns the same rows. The counts were persisted at the suite defaults (`PRED_ROWS=1000000`, `PRED_FILL=30`), so validation assumes those; the `scale` and `width` subgroups pin their own values as template parameters (which win over the environment) and validate at any setting. The template's old `count(*) > 0` assert is dropped as redundant with this. - **`costsel` q04** — the mirror of q03: expensive-selective `regexp_like(s, 'rare')` written before cheap-unselective `c0 < 90`, so the as-written order is already the best one. q03/q04 bracket a reorderer when cost and selectivity point the same way. - **`cardinality` q34 and `load/ints_wide.sql`** — q32's k = 8 predicate over a 64-column table. `c0..c15` reuse `ints.sql`'s multipliers (all coprime to 100), so the hidden selectivities are identical to q32's and only the batch width changes. - **`nulls` subgroup (q90, q91).** `ints.sql` gains `c_sel`, NULL on 10% of rows and uniform on `[0,100)` elsewhere, so `c_sel < 5` is true on exactly 4% of rows. `check_short_circuit` returns `ShortCircuitStrategy::None` as soon as the left-hand boolean array has `null_count() > 0`, so the nullable selective conjunct gates nothing wherever it is written — q90 writes it first, q91 last. No `ints` query references `c_sel`, so their counts are unchanged. - **`drift` down to three cases.** q80 keeps the in-memory dataset, with the flip moved to 2% of the rows so it lands inside the pooled 8-batch warm-up (~65k rows at the default size). The mirrored-order twin was dropped as the same measurement. q82 and q83 share `load/drift_split.sql`: 16 Parquet files of `PRED_ROWS / 16` rows in a gitignored `predicate_eval/scratch/`, `f00..f07` with `a_sel = 0` selective (~0.1%) against `b_sel = 0` at ~50% and `f08..f15` the mirror. `FileGroup::split_files` sorts a group's files by path, so `target_partitions = 1` (q82) reads them in order and meets the flip halfway through one stream, and `= 16` (q83) gives every stream one whole file and one fixed profile — the case a decide-once or shared-decision strategy cannot get right. `repartition_file_scans = false` lives in the shared load file (it stops the groups being re-derived as byte ranges); `target_partitions` differs per query, so each `.benchmark` sets its own in an `init` step. The file names are fixed rather than written by one `COPY ... PARTITIONED BY`, because a directory-target `COPY` names its output with a random write id and Parquet has no overwrite, so the second load of the shared dataset would add files instead of replacing them. - **Shared queries for the knob sweeps.** The template takes a `QUERY` parameter (the path stem under `queries/`), so the `scale` and `width` stubs point at `costsel/q03` and `costsel/q01` rather than keeping seven verbatim copies of two WHERE clauses. - **Docs.** The `predicate_eval` row in `benchmarks/sql_benchmarks/README.md` carries the subgroup list, the result-validation behaviour with its defaults caveat, and the note that the suite sets no engine config of its own; `bench.sh` and the `.suite` description match. ## What is the testing strategy for this PR? No unit tests: these are benchmark definitions, not library code. Verification is that the suite parses, every query runs, and every query's result matches its checked-in expected count. A full run passes on a release build: `benchmark_runner predicate_eval -i 1 --result-mode validate` runs all 31 benchmarks across the ten subgroups and exits 0, and repeats cleanly (the drift `COPY`s overwrite their files rather than accumulating). Validation was checked to actually be checking: overwriting one expected count (`nulls_q90` 20000 → 999999) fails the run with ``` Error: Execution error: Error in result on row 1, column 1 running query "": expected value "999999" but got value "20000" in row: ["20000"] ``` and restoring the file makes it pass again; the same is true of `drift_q83_per_partition_skew` at 991 instead of 992. The drift plans are as intended on both sides (`EXPLAIN`, release build, file list capped at five entries): ``` -- q82, target_partitions = 1 FilterExec: a_sel@0 = 0 AND b_sel@1 = 0, projection=[] DataSourceExec: file_groups={1 group: [[.../drift_split/f00.parquet, .../f01.parquet, .../f02.parquet, .../f03.parquet, .../f04.parquet, ...]]}, projection=[a_sel, b_sel], file_type=parquet, predicate=a_sel@1 = 0 AND b_sel@2 = 0, ... -- q83, target_partitions = 16 FilterExec: a_sel@0 = 0 AND b_sel@1 = 0, projection=[] DataSourceExec: file_groups={16 groups: [[.../drift_split/f00.parquet], [.../f01.parquet], [.../f02.parquet], [.../f03.parquet], [.../f04.parquet], ...]}, projection=[a_sel, b_sel], file_type=parquet, predicate=a_sel@1 = 0 AND b_sel@2 = 0, ... ``` Both settings were checked to be load-bearing by dropping them: without q82's `init` the plan no longer contains `file_groups={1 group`, and with `repartition_file_scans` left on, q83 plans as `file_groups={12 groups: [[.../f00.parquet:0..224901, .../f01.parquet:0..74967], ...]}` — both profiles in one stream. That the read order is deterministic is what q82 relies on, and it is: `FileGroup::split_files` sorts a group's files by path before chunking them ([`file_groups.rs`](https://github.com/apache/datafusion/blob/main/datafusion/datasource/src/file_groups.rs#L459-L462), whose comment says why: `ObjectStore::list` gives no order), and `FileStream` scans a group's files in order. The datasets were verified directly too: `c_sel` is NULL on exactly 100000 rows and `< 5` on 40000 at `PRED_ROWS=1000000`; the split dataset has 62500 rows per file, `a_sel = 0` on 62 of them and `b_sel = 0` on 31250 in `f00..f07`, mirrored in `f08..f15`, and 992 rows matching both over the whole table. q34 and q32 have identical selectivities (both `count(*) = 5000` at `PRED_ROWS=100000`). ## Are there any user-facing changes? No. Benchmark definitions only; nothing in this PR is part of any public API or affects query execution. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Fable 5.1 <[email protected]> --- benchmarks/bench.sh | 10 ++- benchmarks/sql_benchmarks/README.md | 2 +- .../benchmarks/cardinality/q30.benchmark | 3 +- .../benchmarks/cardinality/q31.benchmark | 3 +- .../benchmarks/cardinality/q32.benchmark | 3 +- .../benchmarks/cardinality/q33.benchmark | 3 +- .../cardinality/{q32.benchmark => q34.benchmark} | 7 +- .../benchmarks/correlation/q70.benchmark | 3 +- .../benchmarks/correlation/q71.benchmark | 3 +- .../benchmarks/correlation/q72.benchmark | 3 +- .../benchmarks/correlation/q73.benchmark | 3 +- .../predicate_eval/benchmarks/cost/q10.benchmark | 3 +- .../predicate_eval/benchmarks/cost/q11.benchmark | 3 +- .../benchmarks/costsel/q01.benchmark | 3 +- .../benchmarks/costsel/q02.benchmark | 3 +- .../benchmarks/costsel/q03.benchmark | 3 +- .../costsel/{q03.benchmark => q04.benchmark} | 5 +- .../predicate_eval/benchmarks/drift/q80.benchmark | 3 +- .../predicate_eval/benchmarks/drift/q81.benchmark | 7 -- .../predicate_eval/benchmarks/drift/q82.benchmark | 10 +++ .../predicate_eval/benchmarks/drift/q83.benchmark | 10 +++ .../benchmarks/neutral/q60.benchmark | 3 +- .../benchmarks/neutral/q61.benchmark | 3 +- .../{neutral/q60.benchmark => nulls/q90.benchmark} | 7 +- .../{neutral/q60.benchmark => nulls/q91.benchmark} | 7 +- .../predicate_eval/benchmarks/scale/q50.benchmark | 3 +- .../predicate_eval/benchmarks/scale/q51.benchmark | 3 +- .../predicate_eval/benchmarks/scale/q52.benchmark | 3 +- .../predicate_eval/benchmarks/scale/q53.benchmark | 3 +- .../benchmarks/selectivity/q20.benchmark | 3 +- .../benchmarks/selectivity/q21.benchmark | 3 +- .../predicate_eval/benchmarks/width/q40.benchmark | 3 +- .../predicate_eval/benchmarks/width/q41.benchmark | 3 +- .../predicate_eval/benchmarks/width/q42.benchmark | 3 +- .../sql_benchmarks/predicate_eval/load/corr.sql | 15 +--- .../predicate_eval/load/corrproxy.sql | 34 +++----- .../sql_benchmarks/predicate_eval/load/drift.sql | 19 ++--- .../predicate_eval/load/drift_split.sql | 96 ++++++++++++++++++++++ .../sql_benchmarks/predicate_eval/load/ints.sql | 13 +-- .../predicate_eval/load/ints_wide.sql | 71 ++++++++++++++++ .../sql_benchmarks/predicate_eval/load/markers.sql | 17 ++-- .../sql_benchmarks/predicate_eval/load/mixed.sql | 16 +--- .../predicate_eval.benchmark.template | 37 +++------ .../predicate_eval/predicate_eval.suite | 2 +- .../predicate_eval/queries/cardinality/q30.sql | 4 +- .../predicate_eval/queries/cardinality/q31.sql | 2 +- .../predicate_eval/queries/cardinality/q32.sql | 2 +- .../predicate_eval/queries/cardinality/q33.sql | 2 +- .../queries/cardinality/{q32.sql => q34.sql} | 2 +- .../predicate_eval/queries/correlation/q70.sql | 4 +- .../predicate_eval/queries/correlation/q71.sql | 4 +- .../predicate_eval/queries/correlation/q72.sql | 4 +- .../predicate_eval/queries/correlation/q73.sql | 10 +-- .../predicate_eval/queries/cost/q10.sql | 4 +- .../predicate_eval/queries/cost/q11.sql | 3 +- .../predicate_eval/queries/costsel/q01.sql | 6 +- .../predicate_eval/queries/costsel/q02.sql | 3 +- .../predicate_eval/queries/costsel/q03.sql | 4 +- .../predicate_eval/queries/costsel/q04.sql | 4 + .../predicate_eval/queries/drift/q80.sql | 6 +- .../predicate_eval/queries/drift/q81.sql | 5 -- .../predicate_eval/queries/drift/q82.sql | 5 ++ .../predicate_eval/queries/drift/q83.sql | 5 ++ .../predicate_eval/queries/neutral/q60.sql | 3 +- .../predicate_eval/queries/neutral/q61.sql | 4 +- .../predicate_eval/queries/nulls/q90.sql | 6 ++ .../predicate_eval/queries/nulls/q91.sql | 5 ++ .../predicate_eval/queries/scale/q50.sql | 6 -- .../predicate_eval/queries/scale/q51.sql | 4 - .../predicate_eval/queries/scale/q52.sql | 4 - .../predicate_eval/queries/scale/q53.sql | 4 - .../predicate_eval/queries/selectivity/q20.sql | 5 +- .../predicate_eval/queries/selectivity/q21.sql | 3 +- .../predicate_eval/queries/width/q40.sql | 9 -- .../predicate_eval/queries/width/q41.sql | 7 -- .../predicate_eval/queries/width/q42.sql | 7 -- .../predicate_eval/results/cardinality_q30_k2.csv | 2 + .../predicate_eval/results/cardinality_q31_k4.csv | 2 + .../predicate_eval/results/cardinality_q32_k8.csv | 2 + .../predicate_eval/results/cardinality_q33_k16.csv | 2 + .../results/cardinality_q34_k8_wide64.csv | 2 + .../results/correlation_q70_independent.csv | 2 + .../results/correlation_q71_positive.csv | 2 + .../results/correlation_q72_anti.csv | 2 + .../results/correlation_q73_redundant_proxy.csv | 2 + .../results/cost_q10_expensive_first.csv | 2 + .../results/cost_q11_cheap_first.csv | 2 + .../results/costsel_q01_regexp_selective_last.csv | 2 + .../results/costsel_q02_regexp_selective_first.csv | 2 + ..._cheap_unselective_then_expensive_selective.csv | 2 + ..._expensive_selective_then_cheap_unselective.csv | 2 + .../predicate_eval/results/drift_q80_a_then_b.csv | 2 + .../predicate_eval/results/drift_q82_late_flip.csv | 2 + .../results/drift_q83_per_partition_skew.csv | 2 + .../results/neutral_q60_cheap_uniform.csv | 2 + .../results/neutral_q61_expensive_uniform.csv | 2 + .../results/nulls_q90_nullable_selective_first.csv | 2 + .../results/nulls_q91_nullable_selective_last.csv | 2 + .../predicate_eval/results/scale_q50_5k.csv | 2 + .../predicate_eval/results/scale_q51_100k.csv | 2 + .../predicate_eval/results/scale_q52_5m.csv | 2 + .../predicate_eval/results/scale_q53_50m.csv | 2 + .../results/selectivity_q20_unselective_first.csv | 2 + .../results/selectivity_q21_selective_first.csv | 2 + .../predicate_eval/results/width_q40_narrow.csv | 2 + .../predicate_eval/results/width_q41_wide.csv | 2 + .../predicate_eval/results/width_q42_xwide.csv | 2 + .../predicate_eval/scratch/.gitignore | 1 + 108 files changed, 393 insertions(+), 276 deletions(-) diff --git a/benchmarks/bench.sh b/benchmarks/bench.sh index 419fd5be3a..df33d2aec7 100755 --- a/benchmarks/bench.sh +++ b/benchmarks/bench.sh @@ -106,7 +106,7 @@ wide_schema: Small-projection queries on a wide synthetic dataset (10 (runs both 'wide' and 'narrow' subgroups: narrow is an internal baseline; the wide-vs-narrow ratio is the signal) predicate_eval: Conjunctive (AND) filter-evaluation micro-benchmarks; each subgroup is a different predicate pattern, to test how an adaptive predicate-ordering system behaves across them (see https://github.com/apache/datafusion/issues/11262) - (subgroups via BENCH_SUBGROUP: costsel, cost, selectivity, cardinality, width, scale, neutral, correlation, drift) + (subgroups via BENCH_SUBGROUP: costsel, cost, selectivity, cardinality, width, scale, neutral, correlation, drift, nulls) (toggle a system under test with its native DATAFUSION_* env var; size data with PRED_ROWS, string width with PRED_FILL) parquet_row_filter_skip: Per-RG fully-matched RowFilter skip on Parquet (apache/datafusion#23696); clustered string key + low-selectivity range filter + pushdown, so most row groups are fully matched and the per-row RowFilter is skipped on them @@ -876,7 +876,11 @@ run_push_down_topk() { # micro-benchmarks where each subgroup is a different predicate pattern, used to # test how an adaptive predicate-ordering system behaves across them (see # https://github.com/apache/datafusion/issues/11262). Data is generated inline -# by the suite's load SQL, so there is no data step. +# by the suite's load SQL, so there is no data step (drift q82 and q83 share 16 +# small Parquet files written into sql_benchmarks/predicate_eval/scratch/, which +# is gitignored; q82 reads them with target_partitions=1, so the selectivity flip +# lands halfway through one stream, and q83 with 16, so each stream gets one whole +# file and a fixed profile). # # By default the suite measures DataFusion's built-in left-deep AND short-circuit # and sets no engine config of its own. To evaluate a system under test, export @@ -885,7 +889,7 @@ run_push_down_topk() { # DATAFUSION_EXECUTION_ADAPTIVE_FILTER_REORDERING=true ./bench.sh run predicate_eval # Suite-specific knobs (string-substituted into the load SQL, not engine config): # BENCH_SUBGROUP run one subgroup (costsel, cost, selectivity, cardinality, -# width, scale, neutral, correlation, drift) +# width, scale, neutral, correlation, drift, nulls) # PRED_ROWS synthetic row count (default 1_000_000; the scale subgroup # overrides this per query) # PRED_FILL filler chars per marker = string-column width knob diff --git a/benchmarks/sql_benchmarks/README.md b/benchmarks/sql_benchmarks/README.md index 1ce1fa488c..b8bf8adede 100644 --- a/benchmarks/sql_benchmarks/README.md +++ b/benchmarks/sql_benchmarks/README.md @@ -43,7 +43,7 @@ in the community: | `tpcds` | TPC‑DS queries | | `tpch` | TPC‑H queries | | `wide_schema` | Small-projection queries on a wide (1024-col, 256-file) synthetic dataset; runs `wide` + `narrow` subgroups for comparison | -| `predicate_eval` | Conjunctive (AND) filter-evaluation micro-benchmarks; each subgroup is a different predicate pattern, to test how an adaptive predicate-ordering system behaves across them ([#11262](https://github.com/apache/datafusion/issues/11262)). Subgroups (`--subgroup`): `costsel`, `cost`, `selectivity`, `cardinality`, `width`, `scale`, `neutral`, `correlation`, `drift`. Configure the system under test through its DataFusion settings. | +| `predicate_eval` | Conjunctive (AND) filter-evaluation micro-benchmarks; each subgroup is a different predicate pattern, to test how an adaptive predicate-ordering system behaves across them ([#11262](https://github.com/apache/datafusion/issues/11262)). Subgroups (`--subgroup`): `costsel`, `cost`, `selectivity`, `cardinality`, `width`, `scale`, `neutral`, `correlation`, `drift`, `nulls`. The suite sets no engine config of its own, so by default it measures DataFusion's built-in le [...] | `parquet_row_filter_skip` | Micro-benchmark for the per-row-group fully-matched RowFilter skip on Parquet scans ([#23696](https://github.com/apache/datafusion/issues/23696)). Subgroups (`--subgroup`): `skip` (clustered key, most row groups fully matched by statistics so the per-row filter is skipped), `control` (scrambled key, no row group is ever fully matched). Size the data with `PRED_ROWS` and the row-group size with `RG_SIZE`. | # Running Benchmarks diff --git a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/cardinality/q30.benchmark b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/cardinality/q30.benchmark index 760ea2ca90..d404a193d4 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/cardinality/q30.benchmark +++ b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/cardinality/q30.benchmark @@ -1,7 +1,6 @@ subgroup cardinality template sql_benchmarks/predicate_eval/predicate_eval.benchmark.template -SUBGROUP=cardinality -QPAD=30 +QUERY=cardinality/q30 DATASET=ints NAME=cardinality_q30_k2 diff --git a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/cardinality/q31.benchmark b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/cardinality/q31.benchmark index 74f22715d1..54a25337bd 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/cardinality/q31.benchmark +++ b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/cardinality/q31.benchmark @@ -1,7 +1,6 @@ subgroup cardinality template sql_benchmarks/predicate_eval/predicate_eval.benchmark.template -SUBGROUP=cardinality -QPAD=31 +QUERY=cardinality/q31 DATASET=ints NAME=cardinality_q31_k4 diff --git a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/cardinality/q32.benchmark b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/cardinality/q32.benchmark index b6b69c3852..aff0173e3d 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/cardinality/q32.benchmark +++ b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/cardinality/q32.benchmark @@ -1,7 +1,6 @@ subgroup cardinality template sql_benchmarks/predicate_eval/predicate_eval.benchmark.template -SUBGROUP=cardinality -QPAD=32 +QUERY=cardinality/q32 DATASET=ints NAME=cardinality_q32_k8 diff --git a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/cardinality/q33.benchmark b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/cardinality/q33.benchmark index 1260e68137..bb1464d200 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/cardinality/q33.benchmark +++ b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/cardinality/q33.benchmark @@ -1,7 +1,6 @@ subgroup cardinality template sql_benchmarks/predicate_eval/predicate_eval.benchmark.template -SUBGROUP=cardinality -QPAD=33 +QUERY=cardinality/q33 DATASET=ints NAME=cardinality_q33_k16 diff --git a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/cardinality/q32.benchmark b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/cardinality/q34.benchmark similarity index 57% copy from benchmarks/sql_benchmarks/predicate_eval/benchmarks/cardinality/q32.benchmark copy to benchmarks/sql_benchmarks/predicate_eval/benchmarks/cardinality/q34.benchmark index b6b69c3852..c1851e34ad 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/cardinality/q32.benchmark +++ b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/cardinality/q34.benchmark @@ -1,7 +1,6 @@ subgroup cardinality template sql_benchmarks/predicate_eval/predicate_eval.benchmark.template -SUBGROUP=cardinality -QPAD=32 -DATASET=ints -NAME=cardinality_q32_k8 +QUERY=cardinality/q34 +DATASET=ints_wide +NAME=cardinality_q34_k8_wide64 diff --git a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/correlation/q70.benchmark b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/correlation/q70.benchmark index ef20f7dc49..2084ddab97 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/correlation/q70.benchmark +++ b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/correlation/q70.benchmark @@ -1,7 +1,6 @@ subgroup correlation template sql_benchmarks/predicate_eval/predicate_eval.benchmark.template -SUBGROUP=correlation -QPAD=70 +QUERY=correlation/q70 DATASET=corr NAME=correlation_q70_independent diff --git a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/correlation/q71.benchmark b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/correlation/q71.benchmark index 8875f6c44e..cd5e63aa95 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/correlation/q71.benchmark +++ b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/correlation/q71.benchmark @@ -1,7 +1,6 @@ subgroup correlation template sql_benchmarks/predicate_eval/predicate_eval.benchmark.template -SUBGROUP=correlation -QPAD=71 +QUERY=correlation/q71 DATASET=corr NAME=correlation_q71_positive diff --git a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/correlation/q72.benchmark b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/correlation/q72.benchmark index 8109f1439a..e1dfc3fdaf 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/correlation/q72.benchmark +++ b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/correlation/q72.benchmark @@ -1,7 +1,6 @@ subgroup correlation template sql_benchmarks/predicate_eval/predicate_eval.benchmark.template -SUBGROUP=correlation -QPAD=72 +QUERY=correlation/q72 DATASET=corr NAME=correlation_q72_anti diff --git a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/correlation/q73.benchmark b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/correlation/q73.benchmark index cc3f7bcf54..c9a89b1da8 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/correlation/q73.benchmark +++ b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/correlation/q73.benchmark @@ -1,7 +1,6 @@ subgroup correlation template sql_benchmarks/predicate_eval/predicate_eval.benchmark.template -SUBGROUP=correlation -QPAD=73 +QUERY=correlation/q73 DATASET=corrproxy NAME=correlation_q73_redundant_proxy diff --git a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/cost/q10.benchmark b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/cost/q10.benchmark index 9b864b8594..57c7034573 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/cost/q10.benchmark +++ b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/cost/q10.benchmark @@ -1,7 +1,6 @@ subgroup cost template sql_benchmarks/predicate_eval/predicate_eval.benchmark.template -SUBGROUP=cost -QPAD=10 +QUERY=cost/q10 DATASET=mixed NAME=cost_q10_expensive_first diff --git a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/cost/q11.benchmark b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/cost/q11.benchmark index 296ea443b3..30398925cb 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/cost/q11.benchmark +++ b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/cost/q11.benchmark @@ -1,7 +1,6 @@ subgroup cost template sql_benchmarks/predicate_eval/predicate_eval.benchmark.template -SUBGROUP=cost -QPAD=11 +QUERY=cost/q11 DATASET=mixed NAME=cost_q11_cheap_first diff --git a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/costsel/q01.benchmark b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/costsel/q01.benchmark index abedd1d580..123839a2de 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/costsel/q01.benchmark +++ b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/costsel/q01.benchmark @@ -1,7 +1,6 @@ subgroup costsel template sql_benchmarks/predicate_eval/predicate_eval.benchmark.template -SUBGROUP=costsel -QPAD=01 +QUERY=costsel/q01 DATASET=markers NAME=costsel_q01_regexp_selective_last diff --git a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/costsel/q02.benchmark b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/costsel/q02.benchmark index f50aab6642..304e67189d 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/costsel/q02.benchmark +++ b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/costsel/q02.benchmark @@ -1,7 +1,6 @@ subgroup costsel template sql_benchmarks/predicate_eval/predicate_eval.benchmark.template -SUBGROUP=costsel -QPAD=02 +QUERY=costsel/q02 DATASET=markers NAME=costsel_q02_regexp_selective_first diff --git a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/costsel/q03.benchmark b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/costsel/q03.benchmark index 10c4ce184e..d039e6e28d 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/costsel/q03.benchmark +++ b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/costsel/q03.benchmark @@ -1,7 +1,6 @@ subgroup costsel template sql_benchmarks/predicate_eval/predicate_eval.benchmark.template -SUBGROUP=costsel -QPAD=03 +QUERY=costsel/q03 DATASET=mixed NAME=costsel_q03_cheap_unselective_then_expensive_selective diff --git a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/costsel/q03.benchmark b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/costsel/q04.benchmark similarity index 55% copy from benchmarks/sql_benchmarks/predicate_eval/benchmarks/costsel/q03.benchmark copy to benchmarks/sql_benchmarks/predicate_eval/benchmarks/costsel/q04.benchmark index 10c4ce184e..811e5d642a 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/costsel/q03.benchmark +++ b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/costsel/q04.benchmark @@ -1,7 +1,6 @@ subgroup costsel template sql_benchmarks/predicate_eval/predicate_eval.benchmark.template -SUBGROUP=costsel -QPAD=03 +QUERY=costsel/q04 DATASET=mixed -NAME=costsel_q03_cheap_unselective_then_expensive_selective +NAME=costsel_q04_expensive_selective_then_cheap_unselective diff --git a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/drift/q80.benchmark b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/drift/q80.benchmark index 970adc53f8..fcbd32b0bf 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/drift/q80.benchmark +++ b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/drift/q80.benchmark @@ -1,7 +1,6 @@ subgroup drift template sql_benchmarks/predicate_eval/predicate_eval.benchmark.template -SUBGROUP=drift -QPAD=80 +QUERY=drift/q80 DATASET=drift NAME=drift_q80_a_then_b diff --git a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/drift/q81.benchmark b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/drift/q81.benchmark deleted file mode 100644 index 93cde75ffe..0000000000 --- a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/drift/q81.benchmark +++ /dev/null @@ -1,7 +0,0 @@ -subgroup drift - -template sql_benchmarks/predicate_eval/predicate_eval.benchmark.template -SUBGROUP=drift -QPAD=81 -DATASET=drift -NAME=drift_q81_b_then_a diff --git a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/drift/q82.benchmark b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/drift/q82.benchmark new file mode 100644 index 0000000000..8ec68bd5c1 --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/drift/q82.benchmark @@ -0,0 +1,10 @@ +subgroup drift + +template sql_benchmarks/predicate_eval/predicate_eval.benchmark.template +QUERY=drift/q82 +DATASET=drift_split +NAME=drift_q82_late_flip + +# One stream over the whole directory: the flip lands mid-scan. +init +set datafusion.execution.target_partitions = 1; diff --git a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/drift/q83.benchmark b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/drift/q83.benchmark new file mode 100644 index 0000000000..be25d56612 --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/drift/q83.benchmark @@ -0,0 +1,10 @@ +subgroup drift + +template sql_benchmarks/predicate_eval/predicate_eval.benchmark.template +QUERY=drift/q83 +DATASET=drift_split +NAME=drift_q83_per_partition_skew + +# One file per stream: each stream sees a single profile. +init +set datafusion.execution.target_partitions = 16; diff --git a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/neutral/q60.benchmark b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/neutral/q60.benchmark index 039fee622b..5d39993e98 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/neutral/q60.benchmark +++ b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/neutral/q60.benchmark @@ -1,7 +1,6 @@ subgroup neutral template sql_benchmarks/predicate_eval/predicate_eval.benchmark.template -SUBGROUP=neutral -QPAD=60 +QUERY=neutral/q60 DATASET=ints NAME=neutral_q60_cheap_uniform diff --git a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/neutral/q61.benchmark b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/neutral/q61.benchmark index edaf89b471..ec66cdfc39 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/neutral/q61.benchmark +++ b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/neutral/q61.benchmark @@ -1,7 +1,6 @@ subgroup neutral template sql_benchmarks/predicate_eval/predicate_eval.benchmark.template -SUBGROUP=neutral -QPAD=61 +QUERY=neutral/q61 DATASET=markers NAME=neutral_q61_expensive_uniform diff --git a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/neutral/q60.benchmark b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/nulls/q90.benchmark similarity index 54% copy from benchmarks/sql_benchmarks/predicate_eval/benchmarks/neutral/q60.benchmark copy to benchmarks/sql_benchmarks/predicate_eval/benchmarks/nulls/q90.benchmark index 039fee622b..4e82661a56 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/neutral/q60.benchmark +++ b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/nulls/q90.benchmark @@ -1,7 +1,6 @@ -subgroup neutral +subgroup nulls template sql_benchmarks/predicate_eval/predicate_eval.benchmark.template -SUBGROUP=neutral -QPAD=60 +QUERY=nulls/q90 DATASET=ints -NAME=neutral_q60_cheap_uniform +NAME=nulls_q90_nullable_selective_first diff --git a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/neutral/q60.benchmark b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/nulls/q91.benchmark similarity index 54% copy from benchmarks/sql_benchmarks/predicate_eval/benchmarks/neutral/q60.benchmark copy to benchmarks/sql_benchmarks/predicate_eval/benchmarks/nulls/q91.benchmark index 039fee622b..377b139bf0 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/neutral/q60.benchmark +++ b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/nulls/q91.benchmark @@ -1,7 +1,6 @@ -subgroup neutral +subgroup nulls template sql_benchmarks/predicate_eval/predicate_eval.benchmark.template -SUBGROUP=neutral -QPAD=60 +QUERY=nulls/q91 DATASET=ints -NAME=neutral_q60_cheap_uniform +NAME=nulls_q91_nullable_selective_last diff --git a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/scale/q50.benchmark b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/scale/q50.benchmark index 0bef31e14f..1c8f2c148f 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/scale/q50.benchmark +++ b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/scale/q50.benchmark @@ -1,8 +1,7 @@ subgroup scale template sql_benchmarks/predicate_eval/predicate_eval.benchmark.template -SUBGROUP=scale -QPAD=50 +QUERY=costsel/q03 DATASET=mixed PRED_ROWS=5000 NAME=scale_q50_5k diff --git a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/scale/q51.benchmark b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/scale/q51.benchmark index 8f1315fb11..52bd2a0fd0 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/scale/q51.benchmark +++ b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/scale/q51.benchmark @@ -1,8 +1,7 @@ subgroup scale template sql_benchmarks/predicate_eval/predicate_eval.benchmark.template -SUBGROUP=scale -QPAD=51 +QUERY=costsel/q03 DATASET=mixed PRED_ROWS=100000 NAME=scale_q51_100k diff --git a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/scale/q52.benchmark b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/scale/q52.benchmark index 7ddbfc19b4..9b37a48627 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/scale/q52.benchmark +++ b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/scale/q52.benchmark @@ -1,8 +1,7 @@ subgroup scale template sql_benchmarks/predicate_eval/predicate_eval.benchmark.template -SUBGROUP=scale -QPAD=52 +QUERY=costsel/q03 DATASET=mixed PRED_ROWS=5000000 NAME=scale_q52_5m diff --git a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/scale/q53.benchmark b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/scale/q53.benchmark index 6cea5c44a1..9839289113 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/scale/q53.benchmark +++ b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/scale/q53.benchmark @@ -1,8 +1,7 @@ subgroup scale template sql_benchmarks/predicate_eval/predicate_eval.benchmark.template -SUBGROUP=scale -QPAD=53 +QUERY=costsel/q03 DATASET=mixed PRED_ROWS=50000000 NAME=scale_q53_50m diff --git a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/selectivity/q20.benchmark b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/selectivity/q20.benchmark index 077a62650d..f587dc50d9 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/selectivity/q20.benchmark +++ b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/selectivity/q20.benchmark @@ -1,7 +1,6 @@ subgroup selectivity template sql_benchmarks/predicate_eval/predicate_eval.benchmark.template -SUBGROUP=selectivity -QPAD=20 +QUERY=selectivity/q20 DATASET=ints NAME=selectivity_q20_unselective_first diff --git a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/selectivity/q21.benchmark b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/selectivity/q21.benchmark index 24fc6ef4cd..655b067211 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/selectivity/q21.benchmark +++ b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/selectivity/q21.benchmark @@ -1,7 +1,6 @@ subgroup selectivity template sql_benchmarks/predicate_eval/predicate_eval.benchmark.template -SUBGROUP=selectivity -QPAD=21 +QUERY=selectivity/q21 DATASET=ints NAME=selectivity_q21_selective_first diff --git a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/width/q40.benchmark b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/width/q40.benchmark index df66cf16a3..186fafc40b 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/width/q40.benchmark +++ b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/width/q40.benchmark @@ -1,8 +1,7 @@ subgroup width template sql_benchmarks/predicate_eval/predicate_eval.benchmark.template -SUBGROUP=width -QPAD=40 +QUERY=costsel/q01 DATASET=markers PRED_FILL=2 NAME=width_q40_narrow diff --git a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/width/q41.benchmark b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/width/q41.benchmark index c260dc9985..16967c4d87 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/width/q41.benchmark +++ b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/width/q41.benchmark @@ -1,8 +1,7 @@ subgroup width template sql_benchmarks/predicate_eval/predicate_eval.benchmark.template -SUBGROUP=width -QPAD=41 +QUERY=costsel/q01 DATASET=markers PRED_FILL=30 NAME=width_q41_wide diff --git a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/width/q42.benchmark b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/width/q42.benchmark index 988ff59c70..44ebe3137d 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/width/q42.benchmark +++ b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/width/q42.benchmark @@ -1,8 +1,7 @@ subgroup width template sql_benchmarks/predicate_eval/predicate_eval.benchmark.template -SUBGROUP=width -QPAD=42 +QUERY=costsel/q01 DATASET=markers PRED_FILL=170 NAME=width_q42_xwide diff --git a/benchmarks/sql_benchmarks/predicate_eval/load/corr.sql b/benchmarks/sql_benchmarks/predicate_eval/load/corr.sql index 2d7ceb73e6..946a999ceb 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/load/corr.sql +++ b/benchmarks/sql_benchmarks/predicate_eval/load/corr.sql @@ -1,15 +1,6 @@ --- Correlation dataset: a base column plus derived columns that control the --- *conditional* selectivity of one predicate given another (its selectivity --- among the rows that already passed the other). --- --- x uniform [0,100) --- x_pos = x (perfectly positively correlated: `x<k AND x_pos<k` --- passes ~k%, not the ~k%^2 an independence assumption --- predicts) --- x_anti = 99 - x (anti-correlated: `x<k AND x_anti<k` is empty for k<=50) --- ind independent control column, uniform [0,100) --- --- PRED_ROWS sizes the table. +-- Correlation dataset: `x` uniform on [0,100); `x_pos` = x (perfectly positively +-- correlated); `x_anti` = 99 - x (anti-correlated); `ind` uniform on [0,100) and +-- independent of x. PRED_ROWS sizes the table. CREATE TABLE t AS SELECT (value * 7) % 100 AS x, diff --git a/benchmarks/sql_benchmarks/predicate_eval/load/corrproxy.sql b/benchmarks/sql_benchmarks/predicate_eval/load/corrproxy.sql index f06e68d38c..e17d0d4925 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/load/corrproxy.sql +++ b/benchmarks/sql_benchmarks/predicate_eval/load/corrproxy.sql @@ -1,30 +1,20 @@ --- Correlated-proxy dataset: a cheap integer predicate that is a perfect proxy --- for three string predicates, plus one independent string predicate. --- +-- Correlated-proxy dataset: -- c0 = 1 for ~30% of rows (cheap proxy) --- s1, s2, s3 each contain a marker exactly where c0 = 1 (correlated) --- s4 contains a marker for an independent ~30% (independent) --- --- The four string columns are deliberately *identical in shape*: same width, --- the same single marker at the same offset, each matched by an equally cheap --- regex with the same ~30% marginal selectivity. Marginally the four regex --- predicates are therefore indistinguishable -- same cost, same selectivity, in --- every position -- so neither a marginal cost/selectivity estimator nor --- runtime timing can prefer one over another. Only their *conditional* --- behaviour behind the proxy differs: after `c0 = 1`, the s1/s2/s3 regexes keep --- every survivor (each re-tests the proxy's condition) while the s4 regex still --- discards ~70%. Only joint statistics can see that; an independence assumption --- prices all four regexes identically in every position. +-- s1, s2, s3 each carry a marker exactly where c0 = 1 (correlated) +-- s4 carries a marker for an independent ~30% (independent) +-- PRED_FILL sets the filler width each side of the marker, PRED_ROWS the row count. -- --- PRED_FILL sets the filler width on each side of the marker (a non-matching --- `regexp_like` must scan the whole value), and PRED_ROWS sizes the table. +-- The four string columns are identical in shape -- same width, same marker +-- offset, same regex cost, same ~30% marginal selectivity -- so marginally they +-- are indistinguishable in every position. Only their joint distribution with the +-- proxy differs: after `c0 = 1` the s1/s2/s3 regexes keep every survivor while s4 +-- still discards ~70%. Ranking them therefore takes joint statistics; an +-- independence assumption prices all four regexes identically everywhere. CREATE TABLE t AS WITH base AS ( SELECT - -- The cheap proxy and the independent control share one definition each, so - -- the perfect-proxy / independence invariants can't drift apart silently. - (value * 7) % 100 < 30 AS proxy, -- ~30%, drives c0 and s1/s2/s3 - (value * 13) % 100 < 30 AS indep -- ~30%, independent of proxy, drives s4 + (value * 7) % 100 < 30 AS proxy, + (value * 13) % 100 < 30 AS indep FROM generate_series(1, ${PRED_ROWS:-1000000}) ) SELECT diff --git a/benchmarks/sql_benchmarks/predicate_eval/load/drift.sql b/benchmarks/sql_benchmarks/predicate_eval/load/drift.sql index d5635d91dd..0345abc3f2 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/load/drift.sql +++ b/benchmarks/sql_benchmarks/predicate_eval/load/drift.sql @@ -1,16 +1,11 @@ --- Drift dataset: two predicates whose *relative* selectivity flips partway --- through the scan, so whole-table selectivity differs from per-batch --- selectivity. Rows are emitted in `seq` order, so batches observe the drift in --- order. --- --- a_sel = 0 is selective (~0.1%) in the first 10% of rows, unselective --- (~50%) afterwards. --- b_sel = 0 is the mirror: unselective early, selective late. --- --- PRED_ROWS sizes the table. +-- Drift dataset: rows are emitted in `seq` order and which predicate is more +-- selective flips partway through, so whole-table selectivity differs from +-- per-batch selectivity. `a_sel = 0` matches ~0.1% over the first 2% of rows and +-- ~50% after; `b_sel = 0` is the mirror. At the default PRED_ROWS, which sizes the +-- table, that flip lands inside the pooled 8-batch warm-up (~65k rows). CREATE TABLE t AS SELECT value AS seq, - CASE WHEN value < ${PRED_ROWS:-1000000} / 10 THEN value % 1000 ELSE value % 2 END AS a_sel, - CASE WHEN value < ${PRED_ROWS:-1000000} / 10 THEN value % 2 ELSE value % 1000 END AS b_sel + CASE WHEN value < ${PRED_ROWS:-1000000} / 50 THEN value % 1000 ELSE value % 2 END AS a_sel, + CASE WHEN value < ${PRED_ROWS:-1000000} / 50 THEN value % 2 ELSE value % 1000 END AS b_sel FROM generate_series(1, ${PRED_ROWS:-1000000}); diff --git a/benchmarks/sql_benchmarks/predicate_eval/load/drift_split.sql b/benchmarks/sql_benchmarks/predicate_eval/load/drift_split.sql new file mode 100644 index 0000000000..b36a0d122f --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/load/drift_split.sql @@ -0,0 +1,96 @@ +-- Split drift dataset, shared by q82 and q83: 16 Parquet files of PRED_ROWS / 16 +-- rows each, at the q80 rates -- f00..f07 carry profile A (`a_sel = 0` selective +-- at ~0.1%, `b_sel = 0` unselective at ~50%) and f08..f15 the mirror. +-- +-- One `COPY` per file, because a directory-target `COPY` names its output with a +-- random write id and Parquet has no overwrite, so a second load would add files; +-- the names are zero-padded so they sort numerically. `FileGroup::split_files` +-- sorts a group's files by path, so `target_partitions = 1` (q82) reads f00..f15 +-- in order and `= 16` (q83) gives each stream one whole file; each query sets it. +-- `repartition_file_scans` stays off, or both profiles land in one stream again. + +COPY (SELECT value AS seq, value % 1000 AS a_sel, value % 2 AS b_sel + FROM generate_series(1, ${PRED_ROWS:-1000000} / 16) ORDER BY value) +TO 'sql_benchmarks/predicate_eval/scratch/drift_split/f00.parquet' +STORED AS PARQUET; + +COPY (SELECT value AS seq, value % 1000 AS a_sel, value % 2 AS b_sel + FROM generate_series(1, ${PRED_ROWS:-1000000} / 16) ORDER BY value) +TO 'sql_benchmarks/predicate_eval/scratch/drift_split/f01.parquet' +STORED AS PARQUET; + +COPY (SELECT value AS seq, value % 1000 AS a_sel, value % 2 AS b_sel + FROM generate_series(1, ${PRED_ROWS:-1000000} / 16) ORDER BY value) +TO 'sql_benchmarks/predicate_eval/scratch/drift_split/f02.parquet' +STORED AS PARQUET; + +COPY (SELECT value AS seq, value % 1000 AS a_sel, value % 2 AS b_sel + FROM generate_series(1, ${PRED_ROWS:-1000000} / 16) ORDER BY value) +TO 'sql_benchmarks/predicate_eval/scratch/drift_split/f03.parquet' +STORED AS PARQUET; + +COPY (SELECT value AS seq, value % 1000 AS a_sel, value % 2 AS b_sel + FROM generate_series(1, ${PRED_ROWS:-1000000} / 16) ORDER BY value) +TO 'sql_benchmarks/predicate_eval/scratch/drift_split/f04.parquet' +STORED AS PARQUET; + +COPY (SELECT value AS seq, value % 1000 AS a_sel, value % 2 AS b_sel + FROM generate_series(1, ${PRED_ROWS:-1000000} / 16) ORDER BY value) +TO 'sql_benchmarks/predicate_eval/scratch/drift_split/f05.parquet' +STORED AS PARQUET; + +COPY (SELECT value AS seq, value % 1000 AS a_sel, value % 2 AS b_sel + FROM generate_series(1, ${PRED_ROWS:-1000000} / 16) ORDER BY value) +TO 'sql_benchmarks/predicate_eval/scratch/drift_split/f06.parquet' +STORED AS PARQUET; + +COPY (SELECT value AS seq, value % 1000 AS a_sel, value % 2 AS b_sel + FROM generate_series(1, ${PRED_ROWS:-1000000} / 16) ORDER BY value) +TO 'sql_benchmarks/predicate_eval/scratch/drift_split/f07.parquet' +STORED AS PARQUET; + +COPY (SELECT value AS seq, value % 2 AS a_sel, value % 1000 AS b_sel + FROM generate_series(1, ${PRED_ROWS:-1000000} / 16) ORDER BY value) +TO 'sql_benchmarks/predicate_eval/scratch/drift_split/f08.parquet' +STORED AS PARQUET; + +COPY (SELECT value AS seq, value % 2 AS a_sel, value % 1000 AS b_sel + FROM generate_series(1, ${PRED_ROWS:-1000000} / 16) ORDER BY value) +TO 'sql_benchmarks/predicate_eval/scratch/drift_split/f09.parquet' +STORED AS PARQUET; + +COPY (SELECT value AS seq, value % 2 AS a_sel, value % 1000 AS b_sel + FROM generate_series(1, ${PRED_ROWS:-1000000} / 16) ORDER BY value) +TO 'sql_benchmarks/predicate_eval/scratch/drift_split/f10.parquet' +STORED AS PARQUET; + +COPY (SELECT value AS seq, value % 2 AS a_sel, value % 1000 AS b_sel + FROM generate_series(1, ${PRED_ROWS:-1000000} / 16) ORDER BY value) +TO 'sql_benchmarks/predicate_eval/scratch/drift_split/f11.parquet' +STORED AS PARQUET; + +COPY (SELECT value AS seq, value % 2 AS a_sel, value % 1000 AS b_sel + FROM generate_series(1, ${PRED_ROWS:-1000000} / 16) ORDER BY value) +TO 'sql_benchmarks/predicate_eval/scratch/drift_split/f12.parquet' +STORED AS PARQUET; + +COPY (SELECT value AS seq, value % 2 AS a_sel, value % 1000 AS b_sel + FROM generate_series(1, ${PRED_ROWS:-1000000} / 16) ORDER BY value) +TO 'sql_benchmarks/predicate_eval/scratch/drift_split/f13.parquet' +STORED AS PARQUET; + +COPY (SELECT value AS seq, value % 2 AS a_sel, value % 1000 AS b_sel + FROM generate_series(1, ${PRED_ROWS:-1000000} / 16) ORDER BY value) +TO 'sql_benchmarks/predicate_eval/scratch/drift_split/f14.parquet' +STORED AS PARQUET; + +COPY (SELECT value AS seq, value % 2 AS a_sel, value % 1000 AS b_sel + FROM generate_series(1, ${PRED_ROWS:-1000000} / 16) ORDER BY value) +TO 'sql_benchmarks/predicate_eval/scratch/drift_split/f15.parquet' +STORED AS PARQUET; + +set datafusion.optimizer.repartition_file_scans = false; + +CREATE EXTERNAL TABLE t +STORED AS PARQUET +LOCATION 'sql_benchmarks/predicate_eval/scratch/drift_split/'; diff --git a/benchmarks/sql_benchmarks/predicate_eval/load/ints.sql b/benchmarks/sql_benchmarks/predicate_eval/load/ints.sql index 1d3f030915..f36b283c2a 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/load/ints.sql +++ b/benchmarks/sql_benchmarks/predicate_eval/load/ints.sql @@ -1,8 +1,8 @@ --- Sixteen independent integer columns, each uniform on [0,100). The predicate --- `cN < k` therefore has selectivity ~k%. All columns are equally cheap to --- evaluate, so only selectivity (not cost) distinguishes orderings here. The --- multipliers are all coprime to 100, which keeps the residues uniform and the --- columns mutually decorrelated. PRED_ROWS sizes the table. +-- Seventeen integer columns: c0..c15 uniform on [0,100), so `cN < k` has +-- selectivity ~k%, all equally cheap and mutually decorrelated (the multipliers +-- are coprime to 100); plus `c_sel`, NULL on 10% of rows and uniform on [0,100) +-- elsewhere, so `c_sel < 5` is true on 4% of rows and NULL on 10% -- a selective +-- conjunct that is not NULL-free. PRED_ROWS sizes the table. CREATE TABLE t AS SELECT (value * 1) % 100 AS c0, @@ -20,5 +20,6 @@ SELECT (value * 31) % 100 AS c12, (value * 33) % 100 AS c13, (value * 37) % 100 AS c14, - (value * 39) % 100 AS c15 + (value * 39) % 100 AS c15, + CASE WHEN value % 10 = 0 THEN NULL ELSE (value * 11) % 100 END AS c_sel FROM generate_series(1, ${PRED_ROWS:-1000000}); diff --git a/benchmarks/sql_benchmarks/predicate_eval/load/ints_wide.sql b/benchmarks/sql_benchmarks/predicate_eval/load/ints_wide.sql new file mode 100644 index 0000000000..cddce6f8e5 --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/load/ints_wide.sql @@ -0,0 +1,71 @@ +-- `ints.sql` widened to 64 integer columns, each uniform on [0,100), so `cN < k` +-- again has selectivity ~k%. c0..c15 reuse the same multipliers, so a predicate +-- over them has exactly the same selectivities as on `ints` and only the width of +-- the batches flowing through the filter changes. PRED_ROWS sizes the table. +CREATE TABLE t AS +SELECT + (value * 1) % 100 AS c0, + (value * 3) % 100 AS c1, + (value * 7) % 100 AS c2, + (value * 9) % 100 AS c3, + (value * 11) % 100 AS c4, + (value * 13) % 100 AS c5, + (value * 17) % 100 AS c6, + (value * 19) % 100 AS c7, + (value * 21) % 100 AS c8, + (value * 23) % 100 AS c9, + (value * 27) % 100 AS c10, + (value * 29) % 100 AS c11, + (value * 31) % 100 AS c12, + (value * 33) % 100 AS c13, + (value * 37) % 100 AS c14, + (value * 39) % 100 AS c15, + (value * 41) % 100 AS c16, + (value * 43) % 100 AS c17, + (value * 47) % 100 AS c18, + (value * 49) % 100 AS c19, + (value * 51) % 100 AS c20, + (value * 53) % 100 AS c21, + (value * 57) % 100 AS c22, + (value * 59) % 100 AS c23, + (value * 61) % 100 AS c24, + (value * 63) % 100 AS c25, + (value * 67) % 100 AS c26, + (value * 69) % 100 AS c27, + (value * 71) % 100 AS c28, + (value * 73) % 100 AS c29, + (value * 77) % 100 AS c30, + (value * 79) % 100 AS c31, + (value * 81) % 100 AS c32, + (value * 83) % 100 AS c33, + (value * 87) % 100 AS c34, + (value * 89) % 100 AS c35, + (value * 91) % 100 AS c36, + (value * 93) % 100 AS c37, + (value * 97) % 100 AS c38, + (value * 99) % 100 AS c39, + (value * 101) % 100 AS c40, + (value * 103) % 100 AS c41, + (value * 107) % 100 AS c42, + (value * 109) % 100 AS c43, + (value * 111) % 100 AS c44, + (value * 113) % 100 AS c45, + (value * 117) % 100 AS c46, + (value * 119) % 100 AS c47, + (value * 121) % 100 AS c48, + (value * 123) % 100 AS c49, + (value * 127) % 100 AS c50, + (value * 129) % 100 AS c51, + (value * 131) % 100 AS c52, + (value * 133) % 100 AS c53, + (value * 137) % 100 AS c54, + (value * 139) % 100 AS c55, + (value * 141) % 100 AS c56, + (value * 143) % 100 AS c57, + (value * 147) % 100 AS c58, + (value * 149) % 100 AS c59, + (value * 151) % 100 AS c60, + (value * 153) % 100 AS c61, + (value * 157) % 100 AS c62, + (value * 159) % 100 AS c63 +FROM generate_series(1, ${PRED_ROWS:-1000000}); diff --git a/benchmarks/sql_benchmarks/predicate_eval/load/markers.sql b/benchmarks/sql_benchmarks/predicate_eval/load/markers.sql index 6b8fff9385..d1c818fe0f 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/load/markers.sql +++ b/benchmarks/sql_benchmarks/predicate_eval/load/markers.sql @@ -1,15 +1,8 @@ --- Wide-string dataset: five markers embedded in `PRED_FILL`-wide filler so that a --- non-matching `regexp_like` must scan the whole value (every string predicate --- is "expensive"). Selectivities are coprime so the predicates are independent: --- --- 'aaa' present in ~90% of rows (value % 10 <> 0) --- 'bbb' present in ~86% of rows (value % 7 <> 0) --- 'ccc' present in ~80% of rows (value % 5 <> 0) --- 'ddd' present in ~75% of rows (value % 4 <> 0) --- 'rare' present in ~0.1% of rows (value % 1009 = 5) <- the selective one --- --- PRED_FILL sets the filler width per marker (the string-column width knob: ~6*PRED_FILL --- chars per row), and PRED_ROWS sizes the table. +-- Wide-string dataset: one column `s` holding five markers in PRED_FILL-wide +-- filler, so a non-matching `regexp_like` must scan the whole value. 'aaa' ~90%, +-- 'bbb' ~86%, 'ccc' ~80%, 'ddd' ~75%, 'rare' ~0.1%; the moduli are coprime, so the +-- markers are independent. PRED_FILL is the string-width knob (~6*PRED_FILL chars +-- per row) and PRED_ROWS sizes the table. CREATE TABLE t AS SELECT repeat('q', ${PRED_FILL:-30}) diff --git a/benchmarks/sql_benchmarks/predicate_eval/load/mixed.sql b/benchmarks/sql_benchmarks/predicate_eval/load/mixed.sql index a51c1040da..bc931e8a40 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/load/mixed.sql +++ b/benchmarks/sql_benchmarks/predicate_eval/load/mixed.sql @@ -1,15 +1,7 @@ --- Mixed-cost dataset: cheap integer columns (`cN < k` ~ k% selectivity) --- alongside one wide string column carrying three markers matched by expensive --- `regexp_like`: --- --- 'rare' present in ~0.1% of rows (value % 1009 = 5) --- 'ten' present in ~10% of rows (value % 10 = 0) --- 'aaa' present in ~90% of rows (value % 10 <> 0) --- --- This lets a single table mix cheap integer compares with expensive regexp --- scans at independently chosen selectivities (e.g. a cheap, unselective compare --- next to an expensive, selective regexp). PRED_FILL is the string-width knob; --- PRED_ROWS sizes the table. +-- Mixed-cost dataset: cheap integer columns c0..c3 uniform on [0,100) (`cN < k` +-- ~k%) alongside one wide string column `s` carrying three markers matched by an +-- expensive `regexp_like`: 'rare' ~0.1%, 'ten' ~10%, 'aaa' ~90%. PRED_FILL is the +-- string-width knob and PRED_ROWS sizes the table. CREATE TABLE t AS SELECT (value * 1) % 100 AS c0, diff --git a/benchmarks/sql_benchmarks/predicate_eval/predicate_eval.benchmark.template b/benchmarks/sql_benchmarks/predicate_eval/predicate_eval.benchmark.template index e2e3d6175e..766bd20270 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/predicate_eval.benchmark.template +++ b/benchmarks/sql_benchmarks/predicate_eval/predicate_eval.benchmark.template @@ -1,35 +1,22 @@ -# Shared template for every predicate_eval benchmark. Each qNN.benchmark sets -# its `subgroup` directive and then includes this template with parameters: -# SUBGROUP subgroup name, also the query sub-directory (e.g. costsel) -# QPAD zero-padded query id, also the query file stem (e.g. 01) -# DATASET load script stem under load/ (e.g. markers) -# NAME criterion display name (e.g. costsel_q01_regexp_selective_last) -# Optional (consumed by the load scripts via ${...:-default}): -# PRED_ROWS synthetic row count (default 1_000_000) -# PRED_FILL filler chars per marker = string-column width knob (default 30) -# -# The run SQL lives in queries/${SUBGROUP}/q${QPAD}.sql so the WHERE clause is -# readable on its own. The table is always named `t`, so the assert and cleanup -# are uniform across datasets. -# -# The suite is implementation-agnostic and sets no engine config of its own: it -# measures DataFusion's built-in left-deep `AND` short-circuit by default. To -# evaluate a predicate-ordering system under test, set its native config via the -# environment (the bench harness builds its SessionContext with -# SessionConfig::from_env), e.g. -# DATAFUSION_EXECUTION_ADAPTIVE_FILTER_REORDERING=true +# Shared template for every predicate_eval benchmark. Each qNN.benchmark sets its +# `subgroup` directive and includes this template with parameters: +# QUERY query file stem under queries/ (e.g. costsel/q01) +# DATASET load script stem under load/ (e.g. markers) +# NAME criterion display name (e.g. costsel_q01_regexp_selective_last) +# Optional, read by the load scripts as ${...:-default}: +# PRED_ROWS synthetic row count (default 1000000) +# PRED_FILL filler chars per marker, the string-width knob (default 30) +# The knob sweeps reuse another subgroup's query file through QUERY, and the table +# is always named `t`, so cleanup is uniform across datasets. load sql_benchmarks/predicate_eval/load/${DATASET}.sql name ${NAME} group predicate_eval -assert I -SELECT count(*) > 0 FROM t; ----- -true +run sql_benchmarks/predicate_eval/queries/${QUERY}.sql -run sql_benchmarks/predicate_eval/queries/${SUBGROUP}/q${QPAD}.sql +result sql_benchmarks/predicate_eval/results/${NAME}.csv result sql_benchmarks/predicate_eval/results/${NAME}.csv diff --git a/benchmarks/sql_benchmarks/predicate_eval/predicate_eval.suite b/benchmarks/sql_benchmarks/predicate_eval/predicate_eval.suite index af1a326cd8..4ee33994d3 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/predicate_eval.suite +++ b/benchmarks/sql_benchmarks/predicate_eval/predicate_eval.suite @@ -1,4 +1,4 @@ -description = "Conjunctive filter evaluation micro-benchmarks covering predicate cost, selectivity, cardinality, width, scale, correlation, and drift" +description = "Conjunctive filter evaluation micro-benchmarks covering predicate cost, selectivity, cardinality, width, scale, correlation, drift, and nullable predicates" query_pattern = "q{QUERY_ID_PADDED}.benchmark" diff --git a/benchmarks/sql_benchmarks/predicate_eval/queries/cardinality/q30.sql b/benchmarks/sql_benchmarks/predicate_eval/queries/cardinality/q30.sql index 3be840e917..dbd410f957 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/queries/cardinality/q30.sql +++ b/benchmarks/sql_benchmarks/predicate_eval/queries/cardinality/q30.sql @@ -1,6 +1,4 @@ --- Hidden: cheap integer compares; `c1 < 5` matches ~5%, the `c0 < 90` family --- ~90%. k = 2 here. q30..q33 sweep k = 2/4/8/16 with one ~5% predicate written --- last among ~90% ones. +-- k = 2: one ~90% compare then one ~5% compare (q30..q33 sweep k = 2/4/8/16). SELECT count(*) FROM t WHERE c0 < 90 AND c1 < 5; diff --git a/benchmarks/sql_benchmarks/predicate_eval/queries/cardinality/q31.sql b/benchmarks/sql_benchmarks/predicate_eval/queries/cardinality/q31.sql index 4ba84f8124..d21dd6273e 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/queries/cardinality/q31.sql +++ b/benchmarks/sql_benchmarks/predicate_eval/queries/cardinality/q31.sql @@ -1,4 +1,4 @@ --- k = 4: three ~90% compares followed by one ~5% compare. See q30. +-- k = 4: three ~90% compares then one ~5% compare. SELECT count(*) FROM t WHERE c0 < 90 AND c1 < 90 diff --git a/benchmarks/sql_benchmarks/predicate_eval/queries/cardinality/q32.sql b/benchmarks/sql_benchmarks/predicate_eval/queries/cardinality/q32.sql index d9e920cc62..83037bdfc5 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/queries/cardinality/q32.sql +++ b/benchmarks/sql_benchmarks/predicate_eval/queries/cardinality/q32.sql @@ -1,4 +1,4 @@ --- k = 8: seven ~90% compares followed by one ~5% compare. See q30. +-- k = 8: seven ~90% compares then one ~5% compare. SELECT count(*) FROM t WHERE c0 < 90 AND c1 < 90 diff --git a/benchmarks/sql_benchmarks/predicate_eval/queries/cardinality/q33.sql b/benchmarks/sql_benchmarks/predicate_eval/queries/cardinality/q33.sql index 2408427ab7..890ff4205d 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/queries/cardinality/q33.sql +++ b/benchmarks/sql_benchmarks/predicate_eval/queries/cardinality/q33.sql @@ -1,4 +1,4 @@ --- k = 16: fifteen ~90% compares followed by one ~5% compare. See q30. +-- k = 16: fifteen ~90% compares then one ~5% compare. SELECT count(*) FROM t WHERE c0 < 90 AND c1 < 90 diff --git a/benchmarks/sql_benchmarks/predicate_eval/queries/cardinality/q32.sql b/benchmarks/sql_benchmarks/predicate_eval/queries/cardinality/q34.sql similarity index 66% copy from benchmarks/sql_benchmarks/predicate_eval/queries/cardinality/q32.sql copy to benchmarks/sql_benchmarks/predicate_eval/queries/cardinality/q34.sql index d9e920cc62..2c5b586e54 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/queries/cardinality/q32.sql +++ b/benchmarks/sql_benchmarks/predicate_eval/queries/cardinality/q34.sql @@ -1,4 +1,4 @@ --- k = 8: seven ~90% compares followed by one ~5% compare. See q30. +-- k = 8 as in q32, but over the 64-column `ints_wide` table. SELECT count(*) FROM t WHERE c0 < 90 AND c1 < 90 diff --git a/benchmarks/sql_benchmarks/predicate_eval/queries/correlation/q70.sql b/benchmarks/sql_benchmarks/predicate_eval/queries/correlation/q70.sql index 86e33534c7..f9d7017e61 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/queries/correlation/q70.sql +++ b/benchmarks/sql_benchmarks/predicate_eval/queries/correlation/q70.sql @@ -1,6 +1,4 @@ --- Hidden: `x` and `ind` are independent, each ~20%, so the conjunction matches --- ~4% and the second predicate is just as selective among the first's survivors --- as on its own. Baseline for the correlation sweep. cf. q71, q72. +-- Independent: `x` and `ind` are uncorrelated, each ~20%, so the pair matches ~4%. SELECT count(*) FROM t WHERE x < 20 AND ind < 20; diff --git a/benchmarks/sql_benchmarks/predicate_eval/queries/correlation/q71.sql b/benchmarks/sql_benchmarks/predicate_eval/queries/correlation/q71.sql index eda61cc289..4b5925e80a 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/queries/correlation/q71.sql +++ b/benchmarks/sql_benchmarks/predicate_eval/queries/correlation/q71.sql @@ -1,6 +1,4 @@ --- Hidden: `x_pos` is a copy of `x`, so `x < 20 AND x_pos < 20` still matches --- ~20% (not the ~4% independence would imply) -- the second predicate removes --- none of the first's survivors. cf. q70. +-- Positively correlated: `x_pos` is a copy of `x`, so the pair still matches ~20%. SELECT count(*) FROM t WHERE x < 20 AND x_pos < 20; diff --git a/benchmarks/sql_benchmarks/predicate_eval/queries/correlation/q72.sql b/benchmarks/sql_benchmarks/predicate_eval/queries/correlation/q72.sql index ff987524da..63ec8d57de 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/queries/correlation/q72.sql +++ b/benchmarks/sql_benchmarks/predicate_eval/queries/correlation/q72.sql @@ -1,6 +1,4 @@ --- Hidden: `x_anti` is `99 - x`, so `x < 50 AND x_anti < 50` is empty -- the --- second predicate removes all of the first's survivors, though each matches --- ~50% alone. cf. q70. +-- Anti-correlated: `x_anti` is `99 - x`, so the pair is empty though each matches ~50%. SELECT count(*) FROM t WHERE x < 50 AND x_anti < 50; diff --git a/benchmarks/sql_benchmarks/predicate_eval/queries/correlation/q73.sql b/benchmarks/sql_benchmarks/predicate_eval/queries/correlation/q73.sql index 5e1e822e92..6dc76a8cab 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/queries/correlation/q73.sql +++ b/benchmarks/sql_benchmarks/predicate_eval/queries/correlation/q73.sql @@ -1,11 +1,5 @@ --- Hidden: `c0 = 1` is a perfect proxy for the s1/s2/s3 regexes -- after the --- cheap proxy, each of those keeps every survivor while the equally selective --- (~30%) s4 regex still discards ~70%. The optimal order is [c0, s4, s1/s2/s3] --- (one informative regex on 30% of rows, the three redundant ones on 9%), but --- the four regexes are marginally identical -- same width, same marker offset, --- same cost, same selectivity -- so ranking them takes their *joint* --- distribution with the proxy. Written with the redundant regexes first, --- grouped with their proxy, as an author naturally would. +-- Redundant proxy: `c0 = 1` implies the s1/s2/s3 regexes, while the marginally +-- identical s4 regex is independent of it. Written proxy-first, regexes grouped. SELECT count(*) FROM t WHERE c0 = 1 AND regexp_like(s1, 'a.a') diff --git a/benchmarks/sql_benchmarks/predicate_eval/queries/cost/q10.sql b/benchmarks/sql_benchmarks/predicate_eval/queries/cost/q10.sql index b089ebc7a1..cbe0e937ef 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/queries/cost/q10.sql +++ b/benchmarks/sql_benchmarks/predicate_eval/queries/cost/q10.sql @@ -1,6 +1,4 @@ --- Hidden: both predicates match ~10%, but `regexp_like(s, 'ten')` scans the --- string (expensive) while `c0 < 10` is a cheap compare. Equal selectivity, --- unequal cost; expensive one written first. cf. q11 (opposite order). +-- Equal selectivity (~10%), unequal cost: the expensive regexp written first. cf. q11. SELECT count(*) FROM t WHERE regexp_like(s, 'ten') AND c0 < 10; diff --git a/benchmarks/sql_benchmarks/predicate_eval/queries/cost/q11.sql b/benchmarks/sql_benchmarks/predicate_eval/queries/cost/q11.sql index 82d748c93b..54167ff194 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/queries/cost/q11.sql +++ b/benchmarks/sql_benchmarks/predicate_eval/queries/cost/q11.sql @@ -1,5 +1,4 @@ --- Same two predicates as q10 (both ~10%; regexp expensive, compare cheap), --- opposite written order. cf. q10. +-- q10 with the cheap compare written first. SELECT count(*) FROM t WHERE c0 < 10 AND regexp_like(s, 'ten'); diff --git a/benchmarks/sql_benchmarks/predicate_eval/queries/costsel/q01.sql b/benchmarks/sql_benchmarks/predicate_eval/queries/costsel/q01.sql index bc029ed5d8..1618c54814 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/queries/costsel/q01.sql +++ b/benchmarks/sql_benchmarks/predicate_eval/queries/costsel/q01.sql @@ -1,7 +1,5 @@ --- Hidden in the data: the five markers have very different selectivities -- --- 'aaa' ~90%, 'bbb' ~86%, 'ccc' ~80%, 'ddd' ~75%, 'rare' ~0.1% -- while every --- regexp_like costs about the same. 'rare' (most selective) is written last. --- cf. q02 (most selective written first). +-- Five equally expensive regexps of very different selectivity ('rare' ~0.1%, the +-- rest 75-90%), the selective one written last. cf. q02. SELECT count(*) FROM t WHERE regexp_like(s, 'aaa') AND regexp_like(s, 'bbb') diff --git a/benchmarks/sql_benchmarks/predicate_eval/queries/costsel/q02.sql b/benchmarks/sql_benchmarks/predicate_eval/queries/costsel/q02.sql index 7f7fc61831..dc57aa8d88 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/queries/costsel/q02.sql +++ b/benchmarks/sql_benchmarks/predicate_eval/queries/costsel/q02.sql @@ -1,5 +1,4 @@ --- Same predicates and hidden selectivities as q01 ('rare' ~0.1% is the --- selective one, the rest 75-90%), but with 'rare' written first. cf. q01. +-- q01 with the selective regexp written first. SELECT count(*) FROM t WHERE regexp_like(s, 'rare') AND regexp_like(s, 'aaa') diff --git a/benchmarks/sql_benchmarks/predicate_eval/queries/costsel/q03.sql b/benchmarks/sql_benchmarks/predicate_eval/queries/costsel/q03.sql index a583a498b2..a9d110c65a 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/queries/costsel/q03.sql +++ b/benchmarks/sql_benchmarks/predicate_eval/queries/costsel/q03.sql @@ -1,6 +1,4 @@ --- Hidden: `c0 < 90` matches ~90% (cheap integer compare); `regexp_like(s, --- 'rare')` matches ~0.1% (scans the wide string). The cheaper predicate is the --- less selective one. +-- Cheap unselective compare (~90%) then expensive selective regexp (~0.1%). cf. q04. SELECT count(*) FROM t WHERE c0 < 90 AND regexp_like(s, 'rare'); diff --git a/benchmarks/sql_benchmarks/predicate_eval/queries/costsel/q04.sql b/benchmarks/sql_benchmarks/predicate_eval/queries/costsel/q04.sql new file mode 100644 index 0000000000..2c5a253664 --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/queries/costsel/q04.sql @@ -0,0 +1,4 @@ +-- q03 the other way round, so the as-written order is already the best one. +SELECT count(*) FROM t +WHERE regexp_like(s, 'rare') + AND c0 < 90; diff --git a/benchmarks/sql_benchmarks/predicate_eval/queries/drift/q80.sql b/benchmarks/sql_benchmarks/predicate_eval/queries/drift/q80.sql index b8cb61e85a..63e55ce473 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/queries/drift/q80.sql +++ b/benchmarks/sql_benchmarks/predicate_eval/queries/drift/q80.sql @@ -1,7 +1,5 @@ --- The non-obvious property: selectivity changes across the scan. Rows arrive in --- `seq` order; `a_sel = 0` matches ~0.1% in the first 10% of rows and ~50% --- after, `b_sel = 0` is the mirror -- so which predicate is more selective flips --- partway through. cf. q81 (opposite order). +-- Selectivity drifts across the scan: `a_sel = 0` matches ~0.1% over the first 2% +-- of rows and ~50% after, and `b_sel = 0` is the mirror. SELECT count(*) FROM t WHERE a_sel = 0 AND b_sel = 0; diff --git a/benchmarks/sql_benchmarks/predicate_eval/queries/drift/q81.sql b/benchmarks/sql_benchmarks/predicate_eval/queries/drift/q81.sql deleted file mode 100644 index d65ef475cc..0000000000 --- a/benchmarks/sql_benchmarks/predicate_eval/queries/drift/q81.sql +++ /dev/null @@ -1,5 +0,0 @@ --- Same drifting predicates as q80 (a_sel/b_sel flip which is more selective --- partway through the scan), opposite written order. cf. q80. -SELECT count(*) FROM t -WHERE b_sel = 0 - AND a_sel = 0; diff --git a/benchmarks/sql_benchmarks/predicate_eval/queries/drift/q82.sql b/benchmarks/sql_benchmarks/predicate_eval/queries/drift/q82.sql new file mode 100644 index 0000000000..57bb65d216 --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/queries/drift/q82.sql @@ -0,0 +1,5 @@ +-- Late flip: one stream reads f=00..f=15 in order, so the drift lands halfway +-- through the scan and a warm-up-and-freeze decision is wrong for half the rows. +SELECT count(*) FROM t +WHERE a_sel = 0 + AND b_sel = 0; diff --git a/benchmarks/sql_benchmarks/predicate_eval/queries/drift/q83.sql b/benchmarks/sql_benchmarks/predicate_eval/queries/drift/q83.sql new file mode 100644 index 0000000000..7ecc0fb1c5 --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/queries/drift/q83.sql @@ -0,0 +1,5 @@ +-- Per-partition skew: one whole file per stream, so each stream sees a single fixed +-- profile and one pooled decision is backwards for half of them. +SELECT count(*) FROM t +WHERE a_sel = 0 + AND b_sel = 0; diff --git a/benchmarks/sql_benchmarks/predicate_eval/queries/neutral/q60.sql b/benchmarks/sql_benchmarks/predicate_eval/queries/neutral/q60.sql index b217f56953..76f5a154da 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/queries/neutral/q60.sql +++ b/benchmarks/sql_benchmarks/predicate_eval/queries/neutral/q60.sql @@ -1,5 +1,4 @@ --- Hidden: four integer compares of equal cost, each ~50% selective. Nothing is --- selective and the costs are equal, so the predicates are interchangeable. +-- Four equally cheap compares, each ~50%: nothing to reorder. SELECT count(*) FROM t WHERE c0 < 50 AND c1 < 50 diff --git a/benchmarks/sql_benchmarks/predicate_eval/queries/neutral/q61.sql b/benchmarks/sql_benchmarks/predicate_eval/queries/neutral/q61.sql index 7029a3d9f8..43225f2e48 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/queries/neutral/q61.sql +++ b/benchmarks/sql_benchmarks/predicate_eval/queries/neutral/q61.sql @@ -1,6 +1,4 @@ --- Hidden: four regexp scans of about equal cost, all unselective ('aaa' ~90%, --- 'bbb' ~86%, 'ccc' ~80%, 'ddd' ~75%). Like q60 the predicates are --- interchangeable, but here each one is expensive. +-- Four equally expensive regexps, all unselective (75-90%): nothing to reorder. SELECT count(*) FROM t WHERE regexp_like(s, 'aaa') AND regexp_like(s, 'bbb') diff --git a/benchmarks/sql_benchmarks/predicate_eval/queries/nulls/q90.sql b/benchmarks/sql_benchmarks/predicate_eval/queries/nulls/q90.sql new file mode 100644 index 0000000000..ce4e40d9ac --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/queries/nulls/q90.sql @@ -0,0 +1,6 @@ +-- The selective conjunct (~4%) is nullable, so AND pre-selection is disabled and +-- writing it first gates nothing. cf. q91. +SELECT count(*) FROM t +WHERE c_sel < 5 + AND c0 < 90 + AND c1 < 90; diff --git a/benchmarks/sql_benchmarks/predicate_eval/queries/nulls/q91.sql b/benchmarks/sql_benchmarks/predicate_eval/queries/nulls/q91.sql new file mode 100644 index 0000000000..abca8bb1f9 --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/queries/nulls/q91.sql @@ -0,0 +1,5 @@ +-- q90 with the nullable selective conjunct written last, which is the same work. +SELECT count(*) FROM t +WHERE c0 < 90 + AND c1 < 90 + AND c_sel < 5; diff --git a/benchmarks/sql_benchmarks/predicate_eval/queries/scale/q50.sql b/benchmarks/sql_benchmarks/predicate_eval/queries/scale/q50.sql deleted file mode 100644 index 03a0f1c0db..0000000000 --- a/benchmarks/sql_benchmarks/predicate_eval/queries/scale/q50.sql +++ /dev/null @@ -1,6 +0,0 @@ --- Same predicates as costsel/q03 (`c0 < 90` ~90% cheap, `regexp_like(s, 'rare')` --- ~0.1% expensive). q50..q53 sweep table size; here PRED_ROWS=5_000, roughly a --- single batch. -SELECT count(*) FROM t -WHERE c0 < 90 - AND regexp_like(s, 'rare'); diff --git a/benchmarks/sql_benchmarks/predicate_eval/queries/scale/q51.sql b/benchmarks/sql_benchmarks/predicate_eval/queries/scale/q51.sql deleted file mode 100644 index 28174a5df4..0000000000 --- a/benchmarks/sql_benchmarks/predicate_eval/queries/scale/q51.sql +++ /dev/null @@ -1,4 +0,0 @@ --- q50 at PRED_ROWS=100_000 (~12 batches). See q50. -SELECT count(*) FROM t -WHERE c0 < 90 - AND regexp_like(s, 'rare'); diff --git a/benchmarks/sql_benchmarks/predicate_eval/queries/scale/q52.sql b/benchmarks/sql_benchmarks/predicate_eval/queries/scale/q52.sql deleted file mode 100644 index 74938c4634..0000000000 --- a/benchmarks/sql_benchmarks/predicate_eval/queries/scale/q52.sql +++ /dev/null @@ -1,4 +0,0 @@ --- q50 at PRED_ROWS=5_000_000 (~610 batches). See q50. -SELECT count(*) FROM t -WHERE c0 < 90 - AND regexp_like(s, 'rare'); diff --git a/benchmarks/sql_benchmarks/predicate_eval/queries/scale/q53.sql b/benchmarks/sql_benchmarks/predicate_eval/queries/scale/q53.sql deleted file mode 100644 index 8edb4d4a05..0000000000 --- a/benchmarks/sql_benchmarks/predicate_eval/queries/scale/q53.sql +++ /dev/null @@ -1,4 +0,0 @@ --- q50 at PRED_ROWS=50_000_000 (~6100 batches); builds a ~9 GB table. See q50. -SELECT count(*) FROM t -WHERE c0 < 90 - AND regexp_like(s, 'rare'); diff --git a/benchmarks/sql_benchmarks/predicate_eval/queries/selectivity/q20.sql b/benchmarks/sql_benchmarks/predicate_eval/queries/selectivity/q20.sql index 3638f757a7..b834a4bd7b 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/queries/selectivity/q20.sql +++ b/benchmarks/sql_benchmarks/predicate_eval/queries/selectivity/q20.sql @@ -1,6 +1,5 @@ --- Hidden: two equally cheap integer compares of unequal selectivity -- `c4 < 95` --- matches ~95%, `c0 < 5` matches ~5%. Less selective one written first. --- cf. q21 (opposite order). +-- Two equally cheap compares of unequal selectivity (~95%, ~5%), less selective +-- first. cf. q21. SELECT count(*) FROM t WHERE c4 < 95 AND c0 < 5; diff --git a/benchmarks/sql_benchmarks/predicate_eval/queries/selectivity/q21.sql b/benchmarks/sql_benchmarks/predicate_eval/queries/selectivity/q21.sql index 5181faf387..1f8531a510 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/queries/selectivity/q21.sql +++ b/benchmarks/sql_benchmarks/predicate_eval/queries/selectivity/q21.sql @@ -1,5 +1,4 @@ --- Same two equally-cheap compares as q20 (`c4 < 95` ~95%, `c0 < 5` ~5%), --- opposite written order. cf. q20. +-- q20 with the selective compare written first. SELECT count(*) FROM t WHERE c0 < 5 AND c4 < 95; diff --git a/benchmarks/sql_benchmarks/predicate_eval/queries/width/q40.sql b/benchmarks/sql_benchmarks/predicate_eval/queries/width/q40.sql deleted file mode 100644 index 1b3df3e937..0000000000 --- a/benchmarks/sql_benchmarks/predicate_eval/queries/width/q40.sql +++ /dev/null @@ -1,9 +0,0 @@ --- Same predicate set and hidden selectivities as costsel/q01 ('rare' ~0.1%, the --- rest 75-90%); only the string-column width differs across q40/q41/q42. Narrow: --- PRED_FILL=2, ~12 chars/row. -SELECT count(*) FROM t -WHERE regexp_like(s, 'aaa') - AND regexp_like(s, 'bbb') - AND regexp_like(s, 'ccc') - AND regexp_like(s, 'ddd') - AND regexp_like(s, 'rare'); diff --git a/benchmarks/sql_benchmarks/predicate_eval/queries/width/q41.sql b/benchmarks/sql_benchmarks/predicate_eval/queries/width/q41.sql deleted file mode 100644 index a03b576d9c..0000000000 --- a/benchmarks/sql_benchmarks/predicate_eval/queries/width/q41.sql +++ /dev/null @@ -1,7 +0,0 @@ --- q40 with wide strings: PRED_FILL=30, ~186 chars/row. See q40. -SELECT count(*) FROM t -WHERE regexp_like(s, 'aaa') - AND regexp_like(s, 'bbb') - AND regexp_like(s, 'ccc') - AND regexp_like(s, 'ddd') - AND regexp_like(s, 'rare'); diff --git a/benchmarks/sql_benchmarks/predicate_eval/queries/width/q42.sql b/benchmarks/sql_benchmarks/predicate_eval/queries/width/q42.sql deleted file mode 100644 index cb55d828e3..0000000000 --- a/benchmarks/sql_benchmarks/predicate_eval/queries/width/q42.sql +++ /dev/null @@ -1,7 +0,0 @@ --- q40 with extra-wide strings: PRED_FILL=170, ~1KB/row. See q40. -SELECT count(*) FROM t -WHERE regexp_like(s, 'aaa') - AND regexp_like(s, 'bbb') - AND regexp_like(s, 'ccc') - AND regexp_like(s, 'ddd') - AND regexp_like(s, 'rare'); diff --git a/benchmarks/sql_benchmarks/predicate_eval/results/cardinality_q30_k2.csv b/benchmarks/sql_benchmarks/predicate_eval/results/cardinality_q30_k2.csv new file mode 100644 index 0000000000..23d7344bc8 --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/results/cardinality_q30_k2.csv @@ -0,0 +1,2 @@ +count(*) +50000 diff --git a/benchmarks/sql_benchmarks/predicate_eval/results/cardinality_q31_k4.csv b/benchmarks/sql_benchmarks/predicate_eval/results/cardinality_q31_k4.csv new file mode 100644 index 0000000000..94f68af265 --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/results/cardinality_q31_k4.csv @@ -0,0 +1,2 @@ +count(*) +40000 diff --git a/benchmarks/sql_benchmarks/predicate_eval/results/cardinality_q32_k8.csv b/benchmarks/sql_benchmarks/predicate_eval/results/cardinality_q32_k8.csv new file mode 100644 index 0000000000..23d7344bc8 --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/results/cardinality_q32_k8.csv @@ -0,0 +1,2 @@ +count(*) +50000 diff --git a/benchmarks/sql_benchmarks/predicate_eval/results/cardinality_q33_k16.csv b/benchmarks/sql_benchmarks/predicate_eval/results/cardinality_q33_k16.csv new file mode 100644 index 0000000000..6291042419 --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/results/cardinality_q33_k16.csv @@ -0,0 +1,2 @@ +count(*) +10000 diff --git a/benchmarks/sql_benchmarks/predicate_eval/results/cardinality_q34_k8_wide64.csv b/benchmarks/sql_benchmarks/predicate_eval/results/cardinality_q34_k8_wide64.csv new file mode 100644 index 0000000000..23d7344bc8 --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/results/cardinality_q34_k8_wide64.csv @@ -0,0 +1,2 @@ +count(*) +50000 diff --git a/benchmarks/sql_benchmarks/predicate_eval/results/correlation_q70_independent.csv b/benchmarks/sql_benchmarks/predicate_eval/results/correlation_q70_independent.csv new file mode 100644 index 0000000000..23d7344bc8 --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/results/correlation_q70_independent.csv @@ -0,0 +1,2 @@ +count(*) +50000 diff --git a/benchmarks/sql_benchmarks/predicate_eval/results/correlation_q71_positive.csv b/benchmarks/sql_benchmarks/predicate_eval/results/correlation_q71_positive.csv new file mode 100644 index 0000000000..e3795c1d30 --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/results/correlation_q71_positive.csv @@ -0,0 +1,2 @@ +count(*) +200000 diff --git a/benchmarks/sql_benchmarks/predicate_eval/results/correlation_q72_anti.csv b/benchmarks/sql_benchmarks/predicate_eval/results/correlation_q72_anti.csv new file mode 100644 index 0000000000..4303b90458 --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/results/correlation_q72_anti.csv @@ -0,0 +1,2 @@ +count(*) +0 diff --git a/benchmarks/sql_benchmarks/predicate_eval/results/correlation_q73_redundant_proxy.csv b/benchmarks/sql_benchmarks/predicate_eval/results/correlation_q73_redundant_proxy.csv new file mode 100644 index 0000000000..1cabb81336 --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/results/correlation_q73_redundant_proxy.csv @@ -0,0 +1,2 @@ +count(*) +90000 diff --git a/benchmarks/sql_benchmarks/predicate_eval/results/cost_q10_expensive_first.csv b/benchmarks/sql_benchmarks/predicate_eval/results/cost_q10_expensive_first.csv new file mode 100644 index 0000000000..6291042419 --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/results/cost_q10_expensive_first.csv @@ -0,0 +1,2 @@ +count(*) +10000 diff --git a/benchmarks/sql_benchmarks/predicate_eval/results/cost_q11_cheap_first.csv b/benchmarks/sql_benchmarks/predicate_eval/results/cost_q11_cheap_first.csv new file mode 100644 index 0000000000..6291042419 --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/results/cost_q11_cheap_first.csv @@ -0,0 +1,2 @@ +count(*) +10000 diff --git a/benchmarks/sql_benchmarks/predicate_eval/results/costsel_q01_regexp_selective_last.csv b/benchmarks/sql_benchmarks/predicate_eval/results/costsel_q01_regexp_selective_last.csv new file mode 100644 index 0000000000..5eb0b761fa --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/results/costsel_q01_regexp_selective_last.csv @@ -0,0 +1,2 @@ +count(*) +508 diff --git a/benchmarks/sql_benchmarks/predicate_eval/results/costsel_q02_regexp_selective_first.csv b/benchmarks/sql_benchmarks/predicate_eval/results/costsel_q02_regexp_selective_first.csv new file mode 100644 index 0000000000..5eb0b761fa --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/results/costsel_q02_regexp_selective_first.csv @@ -0,0 +1,2 @@ +count(*) +508 diff --git a/benchmarks/sql_benchmarks/predicate_eval/results/costsel_q03_cheap_unselective_then_expensive_selective.csv b/benchmarks/sql_benchmarks/predicate_eval/results/costsel_q03_cheap_unselective_then_expensive_selective.csv new file mode 100644 index 0000000000..1c82d80b6f --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/results/costsel_q03_cheap_unselective_then_expensive_selective.csv @@ -0,0 +1,2 @@ +count(*) +893 diff --git a/benchmarks/sql_benchmarks/predicate_eval/results/costsel_q04_expensive_selective_then_cheap_unselective.csv b/benchmarks/sql_benchmarks/predicate_eval/results/costsel_q04_expensive_selective_then_cheap_unselective.csv new file mode 100644 index 0000000000..1c82d80b6f --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/results/costsel_q04_expensive_selective_then_cheap_unselective.csv @@ -0,0 +1,2 @@ +count(*) +893 diff --git a/benchmarks/sql_benchmarks/predicate_eval/results/drift_q80_a_then_b.csv b/benchmarks/sql_benchmarks/predicate_eval/results/drift_q80_a_then_b.csv new file mode 100644 index 0000000000..c543899cb1 --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/results/drift_q80_a_then_b.csv @@ -0,0 +1,2 @@ +count(*) +1000 diff --git a/benchmarks/sql_benchmarks/predicate_eval/results/drift_q82_late_flip.csv b/benchmarks/sql_benchmarks/predicate_eval/results/drift_q82_late_flip.csv new file mode 100644 index 0000000000..571ea61b27 --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/results/drift_q82_late_flip.csv @@ -0,0 +1,2 @@ +count(*) +992 diff --git a/benchmarks/sql_benchmarks/predicate_eval/results/drift_q83_per_partition_skew.csv b/benchmarks/sql_benchmarks/predicate_eval/results/drift_q83_per_partition_skew.csv new file mode 100644 index 0000000000..571ea61b27 --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/results/drift_q83_per_partition_skew.csv @@ -0,0 +1,2 @@ +count(*) +992 diff --git a/benchmarks/sql_benchmarks/predicate_eval/results/neutral_q60_cheap_uniform.csv b/benchmarks/sql_benchmarks/predicate_eval/results/neutral_q60_cheap_uniform.csv new file mode 100644 index 0000000000..a1c39233b5 --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/results/neutral_q60_cheap_uniform.csv @@ -0,0 +1,2 @@ +count(*) +150000 diff --git a/benchmarks/sql_benchmarks/predicate_eval/results/neutral_q61_expensive_uniform.csv b/benchmarks/sql_benchmarks/predicate_eval/results/neutral_q61_expensive_uniform.csv new file mode 100644 index 0000000000..5d7624926c --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/results/neutral_q61_expensive_uniform.csv @@ -0,0 +1,2 @@ +count(*) +514286 diff --git a/benchmarks/sql_benchmarks/predicate_eval/results/nulls_q90_nullable_selective_first.csv b/benchmarks/sql_benchmarks/predicate_eval/results/nulls_q90_nullable_selective_first.csv new file mode 100644 index 0000000000..ce62ca3d04 --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/results/nulls_q90_nullable_selective_first.csv @@ -0,0 +1,2 @@ +count(*) +20000 diff --git a/benchmarks/sql_benchmarks/predicate_eval/results/nulls_q91_nullable_selective_last.csv b/benchmarks/sql_benchmarks/predicate_eval/results/nulls_q91_nullable_selective_last.csv new file mode 100644 index 0000000000..ce62ca3d04 --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/results/nulls_q91_nullable_selective_last.csv @@ -0,0 +1,2 @@ +count(*) +20000 diff --git a/benchmarks/sql_benchmarks/predicate_eval/results/scale_q50_5k.csv b/benchmarks/sql_benchmarks/predicate_eval/results/scale_q50_5k.csv new file mode 100644 index 0000000000..8cedd33498 --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/results/scale_q50_5k.csv @@ -0,0 +1,2 @@ +count(*) +5 diff --git a/benchmarks/sql_benchmarks/predicate_eval/results/scale_q51_100k.csv b/benchmarks/sql_benchmarks/predicate_eval/results/scale_q51_100k.csv new file mode 100644 index 0000000000..5066201ce8 --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/results/scale_q51_100k.csv @@ -0,0 +1,2 @@ +count(*) +90 diff --git a/benchmarks/sql_benchmarks/predicate_eval/results/scale_q52_5m.csv b/benchmarks/sql_benchmarks/predicate_eval/results/scale_q52_5m.csv new file mode 100644 index 0000000000..41c4f54ec1 --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/results/scale_q52_5m.csv @@ -0,0 +1,2 @@ +count(*) +4461 diff --git a/benchmarks/sql_benchmarks/predicate_eval/results/scale_q53_50m.csv b/benchmarks/sql_benchmarks/predicate_eval/results/scale_q53_50m.csv new file mode 100644 index 0000000000..defd47ee70 --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/results/scale_q53_50m.csv @@ -0,0 +1,2 @@ +count(*) +44600 diff --git a/benchmarks/sql_benchmarks/predicate_eval/results/selectivity_q20_unselective_first.csv b/benchmarks/sql_benchmarks/predicate_eval/results/selectivity_q20_unselective_first.csv new file mode 100644 index 0000000000..23d7344bc8 --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/results/selectivity_q20_unselective_first.csv @@ -0,0 +1,2 @@ +count(*) +50000 diff --git a/benchmarks/sql_benchmarks/predicate_eval/results/selectivity_q21_selective_first.csv b/benchmarks/sql_benchmarks/predicate_eval/results/selectivity_q21_selective_first.csv new file mode 100644 index 0000000000..23d7344bc8 --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/results/selectivity_q21_selective_first.csv @@ -0,0 +1,2 @@ +count(*) +50000 diff --git a/benchmarks/sql_benchmarks/predicate_eval/results/width_q40_narrow.csv b/benchmarks/sql_benchmarks/predicate_eval/results/width_q40_narrow.csv new file mode 100644 index 0000000000..5eb0b761fa --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/results/width_q40_narrow.csv @@ -0,0 +1,2 @@ +count(*) +508 diff --git a/benchmarks/sql_benchmarks/predicate_eval/results/width_q41_wide.csv b/benchmarks/sql_benchmarks/predicate_eval/results/width_q41_wide.csv new file mode 100644 index 0000000000..5eb0b761fa --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/results/width_q41_wide.csv @@ -0,0 +1,2 @@ +count(*) +508 diff --git a/benchmarks/sql_benchmarks/predicate_eval/results/width_q42_xwide.csv b/benchmarks/sql_benchmarks/predicate_eval/results/width_q42_xwide.csv new file mode 100644 index 0000000000..5eb0b761fa --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/results/width_q42_xwide.csv @@ -0,0 +1,2 @@ +count(*) +508 diff --git a/benchmarks/sql_benchmarks/predicate_eval/scratch/.gitignore b/benchmarks/sql_benchmarks/predicate_eval/scratch/.gitignore new file mode 100644 index 0000000000..4bed5da93f --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/scratch/.gitignore @@ -0,0 +1 @@ +*.parquet --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
