diff --git a/benchmarks/bench.sh b/benchmarks/bench.sh index 419fd5be3ad2b..df33d2aec7e54 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 1ce1fa488c6b8..b8bf8adedede2 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 left-deep `AND` short-circuit; point it at a system under test by exporting that system's own DataFusion setting (the harness builds its `SessionConfig` with `SessionConfig::from_env`). Every query is a `count(*)`, and the counts are checked in under `predicate_eval/results/`, so `--result-mode validate` also checks that a reordering under test still returns the same rows; the checked-in 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 per query and validate at any setting). | | `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 760ea2ca902a4..d404a193d4dd3 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 74f22715d1eb6..54a25337bdd65 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 b6b69c3852361..aff0173e3d890 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 1260e68137860..bb1464d200d54 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/q34.benchmark b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/cardinality/q34.benchmark new file mode 100644 index 0000000000000..c1851e34ad130 --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/cardinality/q34.benchmark @@ -0,0 +1,6 @@ +subgroup cardinality + +template sql_benchmarks/predicate_eval/predicate_eval.benchmark.template +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 ef20f7dc495b8..2084ddab97cae 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 8875f6c44e359..cd5e63aa95fb6 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 8109f1439aedb..e1dfc3fdafdaf 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 cc3f7bcf54901..c9a89b1da801f 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 9b864b859457d..57c7034573714 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 296ea443b3fec..30398925cb740 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 abedd1d580831..123839a2defb6 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 f50aab66427ec..304e67189d1e9 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 10c4ce184eb34..d039e6e28dcc0 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/q04.benchmark b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/costsel/q04.benchmark new file mode 100644 index 0000000000000..811e5d642aca1 --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/costsel/q04.benchmark @@ -0,0 +1,6 @@ +subgroup costsel + +template sql_benchmarks/predicate_eval/predicate_eval.benchmark.template +QUERY=costsel/q04 +DATASET=mixed +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 970adc53f8017..fcbd32b0bfd1f 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 93cde75ffef87..0000000000000 --- 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 0000000000000..8ec68bd5c1d91 --- /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 0000000000000..be25d56612e1a --- /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 039fee622b48b..5d39993e98d09 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 edaf89b471c5f..ec66cdfc39786 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/nulls/q90.benchmark b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/nulls/q90.benchmark new file mode 100644 index 0000000000000..4e82661a56ac5 --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/nulls/q90.benchmark @@ -0,0 +1,6 @@ +subgroup nulls + +template sql_benchmarks/predicate_eval/predicate_eval.benchmark.template +QUERY=nulls/q90 +DATASET=ints +NAME=nulls_q90_nullable_selective_first diff --git a/benchmarks/sql_benchmarks/predicate_eval/benchmarks/nulls/q91.benchmark b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/nulls/q91.benchmark new file mode 100644 index 0000000000000..377b139bf0b46 --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/benchmarks/nulls/q91.benchmark @@ -0,0 +1,6 @@ +subgroup nulls + +template sql_benchmarks/predicate_eval/predicate_eval.benchmark.template +QUERY=nulls/q91 +DATASET=ints +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 0bef31e14f402..1c8f2c148f34a 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 8f1315fb113b1..52bd2a0fd0a02 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 7ddbfc19b443d..9b37a4862738a 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 6cea5c44a108b..9839289113b56 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 077a62650d2f0..f587dc50d941d 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 24fc6ef4cd62f..655b067211aed 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 df66cf16a37ec..186fafc40bd93 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 c260dc9985a0c..16967c4d87d66 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 988ff59c70fe5..44ebe3137de13 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 2d7ceb73e608d..946a999ceba28 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 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 a51c1040daca6..bc931e8a40af0 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 0030a7e946eca..4a23594d3b53b 100644 --- a/benchmarks/sql_benchmarks/predicate_eval/predicate_eval.benchmark.template +++ b/benchmarks/sql_benchmarks/predicate_eval/predicate_eval.benchmark.template @@ -1,34 +1,21 @@ -# 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 cleanup sql_benchmarks/predicate_eval/init/cleanup.sql diff --git a/benchmarks/sql_benchmarks/predicate_eval/predicate_eval.suite b/benchmarks/sql_benchmarks/predicate_eval/predicate_eval.suite index af1a326cd8c51..4ee33994d37f4 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 3be840e917383..dbd410f9575a0 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 4ba84f8124be9..d21dd6273eefa 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 d9e920cc62574..83037bdfc5798 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 2408427ab7632..890ff4205d68c 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/q34.sql b/benchmarks/sql_benchmarks/predicate_eval/queries/cardinality/q34.sql new file mode 100644 index 0000000000000..2c5b586e54af8 --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/queries/cardinality/q34.sql @@ -0,0 +1,10 @@ +-- k = 8 as in q32, but over the 64-column `ints_wide` table. +SELECT count(*) FROM t +WHERE c0 < 90 + AND c1 < 90 + AND c2 < 90 + AND c3 < 90 + AND c4 < 90 + AND c5 < 90 + AND c6 < 90 + AND c7 < 5; diff --git a/benchmarks/sql_benchmarks/predicate_eval/queries/correlation/q70.sql b/benchmarks/sql_benchmarks/predicate_eval/queries/correlation/q70.sql index 86e33534c705d..f9d7017e618ce 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 eda61cc289e92..4b5925e80a809 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 ff987524da6ed..63ec8d57de3f4 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 5e1e822e92eca..6dc76a8cab23f 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 b089ebc7a192a..cbe0e937efde7 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 82d748c93b3b2..54167ff19494f 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 bc029ed5d8297..1618c54814cfa 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 7f7fc61831ff0..dc57aa8d88da0 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 a583a498b211c..a9d110c65a058 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 0000000000000..2c5a253664264 --- /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 b8cb61e85a478..63e55ce473a7f 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 d65ef475cc0e0..0000000000000 --- 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 0000000000000..57bb65d2162a3 --- /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 0000000000000..7ecc0fb1c52f4 --- /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 b217f56953272..76f5a154daedf 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 7029a3d9f8f7d..43225f2e4809a 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 0000000000000..ce4e40d9acfa9 --- /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 0000000000000..abca8bb1f90a2 --- /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 03a0f1c0db285..0000000000000 --- 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 28174a5df4f44..0000000000000 --- 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 74938c4634f78..0000000000000 --- 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 8edb4d4a057d2..0000000000000 --- 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 3638f757a720d..b834a4bd7b87a 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 5181faf38784f..1f8531a51077b 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 1b3df3e937eb3..0000000000000 --- 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 a03b576d9c959..0000000000000 --- 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 cb55d828e32ab..0000000000000 --- 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 0000000000000..23d7344bc8c8c --- /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 0000000000000..94f68af265629 --- /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 0000000000000..23d7344bc8c8c --- /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 0000000000000..6291042419967 --- /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 0000000000000..23d7344bc8c8c --- /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 0000000000000..23d7344bc8c8c --- /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 0000000000000..e3795c1d30546 --- /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 0000000000000..4303b90458538 --- /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 0000000000000..1cabb81336225 --- /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 0000000000000..6291042419967 --- /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 0000000000000..6291042419967 --- /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 0000000000000..5eb0b761fa8b7 --- /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 0000000000000..5eb0b761fa8b7 --- /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 0000000000000..1c82d80b6f382 --- /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 0000000000000..1c82d80b6f382 --- /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 0000000000000..c543899cb162a --- /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 0000000000000..571ea61b2741d --- /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 0000000000000..571ea61b2741d --- /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 0000000000000..a1c39233b50b9 --- /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 0000000000000..5d7624926c7c4 --- /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 0000000000000..ce62ca3d04d63 --- /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 0000000000000..ce62ca3d04d63 --- /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 0000000000000..8cedd33498804 --- /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 0000000000000..5066201ce8c28 --- /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 0000000000000..41c4f54ec18eb --- /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 0000000000000..defd47ee70c37 --- /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 0000000000000..23d7344bc8c8c --- /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 0000000000000..23d7344bc8c8c --- /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 0000000000000..5eb0b761fa8b7 --- /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 0000000000000..5eb0b761fa8b7 --- /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 0000000000000..5eb0b761fa8b7 --- /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 0000000000000..4bed5da93fb28 --- /dev/null +++ b/benchmarks/sql_benchmarks/predicate_eval/scratch/.gitignore @@ -0,0 +1 @@ +*.parquet