Skip to main content
Version: 5.7.0

TPC-DS

TPC-DS is Stroppy's decision-support workload. It generates and loads the 24-table TPC-DS schema and runs the 103-query analytical suite against it.

It models the query load of a retail consolidator: store, web, and catalog sales and returns flowing into fact tables against dimension tables for items, customers, dates, and geography. The workload stresses the same surfaces as TPC-H — scans, multi-table joins, aggregation, sorting, subqueries — but at greater width, with snowflaked dimensions and a far larger, more varied query suite.

Use TPC-DS to evaluate:

  • Bulk load throughput for wide, highly-normalized schemas.
  • Star and snowflake join planning and execution.
  • Aggregation, grouping, sorting, and top-N performance across large fact tables.
  • Window-function and correlated-subquery plans (rank, dense_rank, lag, lead).
  • Planner stability across a varied 100+ query suite.
  • Engine correctness via answer-set validation and cross-database diffing.

Script

TPC-DS has one script: tpcds. It supports PostgreSQL, MySQL, Picodata, and YDB.

stroppy run tpcds -d pg -D url=postgres://user:pass@host:5432/bench -e scale_factor=1
stroppy run tpcds -d mysql -D url=root:pass@tcp(host:3306)/bench -e scale_factor=0.1
stroppy run tpcds -d pico -e scale_factor=0.1
stroppy run tpcds -d ydb -D url=grpc://host:2136/database -e scale_factor=0.1

Data Generation

Stroppy generates the dataset itself with a faithful Go port of the official dsdgen, validated byte-for-byte against the reference C generator across all 24 base tables. Generation is parallel and streaming — any table, including the multi-million-row sales and returns fact tables, can be produced in independent partitions with identical output. The workload creates the schema, generates and loads all 24 tables, builds single-table indexes, and runs ANALYZE before the query phase.

SCALE_FACTOR is a fractional row scale. Use 0.1 or 0.01 for smoke tests. Note that some static dimension tables (for example customer_demographics, ~1.9M rows) are fixed-size and do not shrink with the scale factor.

Query Suite

The 103 queries run from per-dialect SQL files generated from the official query templates. Picodata omits 8 queries that sbroad cannot express — query_36, query_44, query_47, query_49, query_57, query_67, query_70, query_86, which need rank/dense_rank/lag/lead and correlated-subquery support — so a Picodata run executes 95 queries and logs the skip once at start.

By default the workload runs the baked canonical query set once (single power-test stream). For a throughput-style run, generate seeded permutations of the query set and drive several concurrent streams:

ENVBehavior
STREAMS=N (N>1)Runs N concurrent VUs, each its own seeded permutation of the queries (throughput test).
QUERY_STREAM=NGenerates query stream N in-process with a fixed seed (single stream).
QUERY_SEEDRNG seed for generated streams.

YDB runs the baked power test only. Setting STREAMS>1 or a non-empty QUERY_STREAM with -d ydb is rejected, because the in-process stream generator cannot target YQL.

Answer Validation

At SCALE_FACTOR=1 on PostgreSQL and MySQL, the workload validates query results against the embedded official SF=1 answer set. Stroppy compares result multisets with numeric tolerance, so engine-specific null and tie ordering is not flagged as a mismatch. Set VALIDATE_FORCE to validate at any scale, and ANSWER_DUMP to dump normalized results to the log for cross-database diffing.

Steps

StepDescription
drop_schemaDrops existing tables (CASCADE), so a re-run against a leftover schema does not fail on dependents.
create_schemaCreates the 24 tables from the dialect schema (schema.pg.sql, schema.mysql.sql, schema.pico.sql, schema.ydb.sql). YDB column mode selects the column-store schema.
set_unloggedPostgreSQL only, when PG_UNLOGGED=true. Flips tables to UNLOGGED before the bulk load.
load_dataGenerates and loads all 24 tables via the native dsdgen path.
create_indexesBuilds single-table indexes after the load so bulk insert is not slowed by index maintenance.
set_loggedPostgreSQL only, when PG_UNLOGGED=true. Flips tables back to LOGGED.
analyzePostgreSQL ANALYZE / MySQL ANALYZE TABLE. No-op on Picodata/YDB.
workloadExecutes the query suite once with pinned parameters and logs per-query duration. Console-silent per iteration. Replaced by validate_answers when validating or dumping.
validate_answersRuns the query suite, captures results, and compares to the SF=1 answer set (PostgreSQL/MySQL at SCALE_FACTOR=1, or when forced). Emits __TPCDS_DUMP__ lines when ANSWER_DUMP is set.

Examples:

stroppy run tpcds -d pg --steps drop_schema,create_schema,load_data
stroppy run tpcds -d pg --steps workload

SQL Files

When SQL_FILE is not set, the script chooses a query file from the active driver type:

Driver typeQuery fileSchema file
postgrestpcds/pg.sqlschema.pg.sql
mysqltpcds/mysql.sqlschema.mysql.sql
picodatatpcds/pico.sqlschema.pico.sql
ydbtpcds/ydb.sqlschema.ydb.sql

Pass an explicit SQL file with SQL_FILE to force a variant:

stroppy run tpcds -d pg -e sql_file=./tpcds/pg.sql

Parameters

Workload parameters are passed as environment variables with -e key=VALUE. Keys are case-insensitive in the CLI.

ParameterDefaultDescription
SCALE_FACTOR1TPC-DS scale factor (fractional).
STREAMS1Concurrent throughput query streams. 1 = single power-test stream.
QUERY_STREAMemptyGenerate query stream N in-process (empty = baked canonical set).
QUERY_SEED19620718RNG seed for generated query streams.
POOL_SIZE50Sets both minConns and maxConns for the primary driver pool.
LOAD_WORKERS0Parallel load workers per table. 0 lets the framework choose.
YDB_STORE_MODEcolumnYDB storage: column (default, OLAP column store) or row.
PG_UNLOGGEDtruePostgreSQL fast bulk-load via UNLOGGED tables, flipped back to LOGGED after load.
SQL_FILEautoQuery SQL file. Defaults to a dialect file based on driverType.
VALIDATE_FORCEemptyForce answer validation at any scale.
ANSWER_DUMPemptyDump normalized query results to the log for cross-database diffing.

TPC-DS queries are read-only and issued outside an explicit transaction; there is no TX_ISOLATION knob.

Metrics

TPC-DS does not define custom k6 Trend or Counter metrics per query. Query timings flow through the common driver metrics during the query phase:

MetricTypeDescription
run_query_countCounterSQL statements executed by the driver.
run_query_durationTrendSQL execution latency samples, tagged by the active step.
run_query_error_rateRateQuery execution failure rate.
insert_durationTrendBulk-load duration samples. Useful for load throughput analysis.
insert_error_rateRateInsert failures during data loading.

For PostgreSQL/MySQL at SCALE_FACTOR=1, validate_answers prints a validation summary against answers_sf1.json, including OK, DIFF, SKIP, and ERROR rows per query.

Thresholds

TPC-DS does not define k6 thresholds by default. The run is not auto-failed by a slow query threshold; correctness is gated by answer-set validation instead.