---
title: 'BaCon-20k: 20K Counting Queries Workload'
url: https://www.emergentmind.com/topics/bacon-20k
type: topic
---

# BaCon-20k: 20K Counting Queries Workload

BaCon-20k denotes the 20,000-query workload associated with BaCon in the paper "BaCon: Efficient Batch Processing of Counting Queries [Full Version]" [2607.05832]. The paper does not use the name "BaCon-20k," but it does use and publish a 20,000-counting-query workload called **dsb-grasp-20k**, which is the only 20k workload used and published with BaCon. In that setting, BaCon is an exact algorithm for batch evaluation of counting queries on top of a database system, without modifying its internals; for dsb-grasp-20k, it evaluates select-join `COUNT(*)` queries by combining workload-aware domain quantization with factorized counting, rather than materializing full join results [2607.05832].

## 1. Definition and provenance

Within the BaCon literature, the relevant 20k object is **dsb-grasp-20k**. It is a batch workload of **20,000 select-join `COUNT(*)` queries** intended for training and evaluating learned cardinality estimation and for benchmarking BaCon’s batch counting performance. It is a **post-processed sample** from an original GRASP workload file containing **149,828 queries** [2607.05832].

The workload is derived from query generators associated with **GRASP** and **SeConCDF** over the **DSB** benchmark. DSB is described as adapting **TPC-DS** for modern workloads, and the instance used in the BaCon paper has **scale factor 2**. The authors removed queries that require undocumented transformations of attributes originally stored as `char(...)`, then **randomly sampled 20,000 queries** so that baselines would complete within a reasonable time [2607.05832].

This provenance is important because the 20k workload is not a synthetic artifact introduced solely for BaCon; it is a curated subset of an existing workload family used in learned cardinality estimation. A plausible implication is that the workload was chosen to preserve realism while making end-to-end runtime comparisons operationally feasible.

## 2. Workload structure and query model

The paper’s summary of query workloads characterizes **dsb-grasp-20k** as follows [2607.05832]:

| Property | Value |
|---|---|
| Database | DSB |
| Number of queries | 20,000 |
| Tables per query | 1 to 5 |
| Distinct join patterns | 16 |

The queries are **acyclic equi-join** counting queries with **no cycles** and **no self-joins**, matching the problem setup assumed by BaCon. Predicates are conjunctions of **single-attribute comparisons with literals** using operators such as `=`, `>`, and `<=`. Range predicates appear, and the workload is described as diverse and realistic for learned cardinality estimation, although the paper does not publish selectivity distributions per attribute for dsb-grasp-20k [2607.05832].

The formal counting query semantics are stated as
$$
C(Q) = | \sigma_P(R_1 \Join R_2 \Join \cdots \Join R_m) |,
$$
where $P$ is a conjunction of single-attribute predicates and the joins are equi-joins across attributes without cycles or self-joins. For dsb-grasp-20k, BaCon computes these counts **exactly** [2607.05832].

No train/validation/test split is reported for dsb-grasp-20k in the BaCon paper. The workload is used to measure **end-to-end batch counting runtimes**, not to define an explicit machine-learning split regime [2607.05832].

## 3. Quantization and exact counting semantics

BaCon processes the workload by first partitioning queries by **join pattern**. For dsb-grasp-20k, this yields **16 partitions**, each corresponding to a join pattern over **1–5 tables** [2607.05832].

Its first core mechanism is **workload-aware domain quantization**. For each selection attribute $A$ referenced by any query in a join pattern, BaCon collects all predicate ranges and constructs a quantization scale by sorting endpoints and converting them into **left-closed/right-open atomic buckets**. Values outside all buckets map to **bucket id 0**. The paper states the guarantee as follows: for each selection predicate $A \in \delta$ in a query $Q$,  
$x \in \delta$ iff $\_A(x) \in f(\_A,\delta)$,  
so selections can be evaluated entirely on integer buckets induced by workload ranges [2607.05832].

The second core mechanism is **factorized counting using conditional orthogonality**. For a star join
$$
E_0 \Join_{\theta_1} E_1 \cdots \Join_{\theta_n} E_n,
$$
fixing the join-attribute values $v(A)$ for the center’s attributes referenced by edges yields
$$
\sigma_{\wedge_{A\in J_0} A = v(A)}(E_0 \Join_{\theta_1} E_1 \cdots \Join_{\theta_n} E_n)
=
\sigma_{\wedge_{A\in J_0} A = v(A)}(E_0)
\times
\sigma_{v\llbracket \theta_1 \rrbracket}(E_1)
\times \cdots \times
\sigma_{v\llbracket \theta_n \rrbracket}(E_n).
$$
BaCon generalizes this to a tree plan, computes per-table projected subslice counts in quantized coordinates, multiplies them within a fixed binding, and adds them across bindings [2607.05832].

The algebraic object used for this purpose is the **count map**. A count map $M$ over a set of tables $S$ maps a grid coordinate $b$ to a count $M[b]$. The two operations are:

- **Multiply**:
  $$
  M_1 \otimes M_2 = \{ b_1 b_2 \to M_1[b_1]\cdot M_2[b_2] \}
  $$
  for disjoint table sets.
- **Add**:
  $$
  M_1 \oplus M_2 = \{ b \to M_1[b] + M_2[b] \}
  $$
  for identical table sets and scales.

The paper’s correctness lemmas for quantization, multiplication, and addition are the basis for the claim that BaCon computes **exact counts** for all queries in dsb-grasp-20k without materializing full joins [2607.05832].

## 4. Execution workflow on dsb-grasp-20k

The high-level algorithm reported for BaCon consists of four stages [2607.05832].

First, it **groups queries by join pattern** and builds the quantization scales for that pattern. Second, it selects a **plan tree** whose root is the **highest-degree table** to maximize sharing; it also applies **FK→PK short-cuts at the root** and **dynamically reorders children** to short-circuit empty subslices. Third, it recursively processes the plan using `Recurse(R,u)`: for each binding of the root’s outgoing join attributes, `ProcessTable` produces coordinate-count pairs for the projected subslice of the current table, child maps are recursively computed, then combined with $\otimes$ and accumulated with $\oplus$. Fourth, `ComputeCounts` scans the final count map and, for each query, checks whether each non-zero coordinate lies inside the query’s bucket ranges; if so, it adds the corresponding count. This step is implemented with **JIT (Numba)** [2607.05832].

The SQL skeleton used in `ProcessTable(R, u, J_out)` is given in the paper as:
```sql
SELECT J1, J2, ..., B1, B2, ..., COUNT(*)
FROM (
    SELECT J1, J2, ..., quantize(S1, _S1) AS B1, ...
    FROM R
    WHERE J1 = u(J1) AND J2 = u(J2) AND ...
)
GROUP BY J1, J2, ..., B1, B2, ...
ORDER BY J1, J2, ...
```

A batched variant replaces point predicates on join bindings with `BETWEEN min(U) AND max(U)` and then post-filters on the returned join attributes. The batching parameter is **$\beta = 50{,}000$**, meaning that bind values are grouped per batch during recursive processing. The appendix studies other values of $\beta$, and the paper states that larger $\beta$ leads to fewer SQL calls and lower fetch overhead [2607.05832].

This workflow makes the workload overlap explicit. Instead of executing 20,000 queries independently, BaCon amortizes repeated structure across queries that share a join pattern and overlapping predicate ranges.

## 5. System realization and performance characteristics

The implementation described in the paper runs as a **client-side application on PostgreSQL** with a lightweight **C-language UDF** named `quantize` [2607.05832]. The experimental configuration for dsb-grasp-20k uses:

- **DBMS**: PostgreSQL v16.8, default configuration  
- **Database scale factor**: DSB scale factor 2  
- **Hardware**: Linux server, Intel Xeon Gold 5215, 40 logical cores at 2.50 GHz, 256 GB RAM, 1 TB disk  
- **Client**: Python 3 with `psycopg2`  
- **Single-threaded setting**: PostgreSQL parallelism disabled via `max_parallel_workers_per_gather = 0`  
- **Cursor policy**: server-side cursor for the root table’s `ProcessTable`; client-side cursors for non-root tables [2607.05832]

For **single-threaded end-to-end runtime** on dsb-grasp-20k, the paper reports [2607.05832]:

| Method | Runtime |
|---|---|
| IndProc | 19,746 s |
| PostFilt | 4,211 s |
| BaCon | 928 s |

The reported speedup of BaCon over IndProc is **21.28×**, and the paper notes that **BaCon never timed out**. Preprocessing overhead, including grouping queries by pattern and parsing, is reported as the largest among the workloads because of the 20k query count, at **approximately 20 s**, but still negligible relative to the **928 s** end-to-end runtime [2607.05832].

For **parallel mode**, with database parallelism enabled and BaCon using simple multi-process execution, the reported runtimes are **6,241 s** for IndProc, **913 s** for PostFilt, and **359 s** for BaCon, corresponding to a **17.37×** speedup over IndProc [2607.05832].

The paper also evaluates a **materialized-view PostFilt variant**, feasible here because the full-join sizes are manageable. For dsb-grasp-20k, standard PostFilt is **4,211 s**, the materialized-view variant is **4,356 s**, and the relevant view cardinalities are reported as **less than $6\cdot 10^6$**. BaCon remains faster than both [2607.05832].

## 6. Heuristics, interpretation, and naming ambiguity

The paper attributes BaCon’s performance to a combination of **quantization**, **factorization**, and **execution heuristics** [2607.05832]. Root selection by highest join degree and **FK→PK short-cuts at the root** reduce enumeration of trivial cross-products and lower descendant-grid dimensionality. **Dynamic child reordering** allows multiply steps to short-circuit when many child subslices are empty. Quantization granularity is induced by the set of workload range endpoints; larger workloads therefore induce more buckets, but selections still align exactly, and each `quantize` call costs **$O(\log |\_A|)$** because the C UDF performs binary search over sorted bucket boundaries [2607.05832].

The paper does not explicitly report the dsb-grasp-20k memory peak, but it states that BaCon’s peak memory footprint is **per-pattern** and that the overall worst case across workloads was **1.7 GB in IMDB synthetic**. For dsb-grasp-20k, the peak was lower, which the paper describes as consistent with smaller induced grids and fewer selection dimensions per pattern [2607.05832]. This suggests that the workload’s structure, rather than the raw count of 20,000 queries alone, is central to the observed resource profile.

A recurrent source of confusion is the name itself. The term **BaCon-20k** does **not** appear in the BaCon paper; the correct workload name is **dsb-grasp-20k** [2607.05832]. This distinction matters because other unrelated arXiv papers also use the name **BaCon** or **BACON**, including "BaCon: Boosting Imbalanced Semi-supervised Learning via Balanced Feature-Level Contrastive Learning" [2403.12986] and "BACON: Bayesian Optimal Condensation Framework for Dataset Distillation" [2406.01112]. Those papers do not define the DSB counting-query workload described here, and the 20k designation in the present context refers specifically to the **20,000-query DSB workload** associated with BaCon’s batch counting system [2607.05832].

The code and artifacts are reported as publicly available at `https://github.com/louisja1/bacon`, with the workload file `dsb_grasp_20k.sql`, the post-processing script `dsb_grasp_csv_to_sql.py`, and the original GRASP CSV linked from the corresponding repositories [2607.05832].

Source: https://www.emergentmind.com/topics/bacon-20k