1 TPC-H
TPC-H Benchmark是由国际事务处理性能委员会(Transaction Processing Performance Council)发布的数据库决策支持测试标准,被工业界和学术界普遍认可,也是作为决策型数据库选型的重要参考指标之一。
TPC-H 是一个决策支持基准(Decision Support Benchmark),它由一套面向业务的特别查询和并发数据修改组成。查询和填充数据库的数据具有广泛的行业相关性。这个基准测试演示了检查大量数据、执行高度复杂的查询并回答关键业务问题的决策支持系统。TPC-H 报告的性能指标称为 TPC-H 每小时复合查询性能指标 (QphH@Size),反映了系统处理查询能力的多个方面。这些方面包括执行查询时所选择的数据库大小,由单个流提交查询时的查询处理能力,以及由多个并发用户提交查询时的查询吞吐量。
这个标准的表结构如下:

TPC-H模型是典型的雪花模型,一共有8张表,其中nation和region两张表的数据量是固定的,其余6张表的数据量跟比例因子SF(Scale Factor)相关,缩放是一个整数,单位为GB,代总的数据量,如指定为10,则代表总的数据量为10GB。
TPC-H标准的数据也是学习数据库技术的很好的实例数据库,它比较接近真实场景。生成这个测试集的常见的方式是从官网下载相应压缩包,运行相应的脚本,步骤比较繁琐,使用duckdb可以简化这个过程,通过调用一个函数生成数据集,生成的数据集也可以使用一条命令直接拷贝到关系数据库如MySQL中。
2 使用duckdb生成TPC-H测试数据
DuckDB 完全用 C++ 编写,是一个采用矢量化执行引擎的数据库管理系统。它是一个进程内数据库引擎,可以将他称为“用于分析的 SQLite”。duckdb可以嵌入程序中使用,也可以下载其cli包来启动一个duckdb数据库,用起来非常简单。
duckdb有着十分灵活的扩展,它的扩展可以动态载入,TPC-H的支持就是通过扩展tpch来提供的,tpch扩展是duckdb的核心扩展,扩展的信息如下
select * from duckdb_extensions() s WHERE extension_name='tpch' ;
extension_name|loaded|installed|install_path |description |aliases|extension_version|
--------------+------+---------+---------------------------------------------------------------------------------+--------------------------------------------+-------+-----------------+
tpch |true |true |C:\Users\lichengxu\.duckdb\extensions\v0.10.2\windows_amd64\tpch.duckdb_extension|Adds TPC-H data generation and query support|[] |1601d94f94 |
2.1查看tpch扩展的相关函数
tpch扩展也提供了几个函数,可以查询运行查询语句,查询TPC-H标准有哪些查询语句等。
SELECT *
FROM duckdb_functions() where function_name like 'tpch%';
database_name|database_oid|schema_name|function_name|function_type|description|comment|return_type|parameters|parameter_types|varargs|macro_definition|has_side_effects|internal|function_oid|example|stability|
-------------+------------+-----------+-------------+-------------+-----------+-------+-----------+----------+---------------+-------+----------------+----------------+--------+------------+-------+---------+
system |0 |main |tpch_answers |table | | | |[] |[] | | | |true | 1944| | |
system |0 |main |tpch_queries |table | | | |[] |[] | | | |true | 1942| | |
system |0 |main |tpch |pragma | | | |['col0'] |['BIGINT'] | | | |true | 1940| | |
创建并切换到schema
CREATE schema tcph;
USE duckdata.tcph;
如果使用现有的schema,可能需要清理一下环境
DROP TABLE IF EXISTS customer;
DROP TABLE IF EXISTS lineitem;
DROP TABLE IF EXISTS nation;
DROP TABLE IF EXISTS orders;
DROP TABLE IF EXISTS part;
DROP TABLE IF EXISTS partsupp;
DROP TABLE IF EXISTS region;
DROP TABLE IF EXISTS supplier;
2.2 生成数据
调用dbgen函数可以直接生成tpch测试数据集,这个函数有多个参数可以控制生成数据集的大小,是否分区,是否分步执行等。
生成函数信息
database_name|database_oid|schema_name|function_name|function_type|description|comment|return_type|parameters |parameter_types |varargs|macro_definition|has_side_effects|internal|function_oid|example|stability|
-------------+------------+-----------+-------------+-------------+-----------+-------+-----------+----------------------------------------------------------------+------------------------------------------------------------------------+-------+----------------+----------------+--------+------------+-------+---------+
system |0 |main |dbgen |table | | | |['step','sf','overwrite','suffix','catalog','schema','children']|['UINTEGER','DOUBLE','BOOLEAN','VARCHAR','VARCHAR','VARCHAR','UINTEGER']| | | |true | 1938| | |
从parameters 列里可以看到这个函数有[‘step’,‘sf’,‘overwrite’,‘suffix’,‘catalog’,‘schema’,‘children’]五个参数,这些参数的类型及解释如下
| 名字 | 类型 | 描述 |
|---|---|---|
| catalog | VARCHAR | 目标catalog |
| children | UINTEGER | 分区数量 |
| overwrite | BOOLEAN | 这个参数目前没有使用 |
| sf | DOUBLE | 缩放因子 |
| step | UINTEGER | 定义要产生的分区,从0到children-1.如果定义了children,必须指定step |
| suffix | VARCHAR | 附加到表名上的后缀 |
缩放因子同产生的数据量的关系如下表
| 缩放因子 | 占用空间 |
|---|---|
| 1 | 250 MB |
| 3 | 754 MB |
| 10 | 2.5 GB |
| 30 | 7.6 GB |
| 100 | 26 GB |
| 300 | 78 GB |
| 1000 | 265 GB |
| 3000 | 796 GB |
在生成的数据量较大时,系统可能没有足够的资源,可以使用分步运行这个函数,比如分10步生成SF300
CALL dbgen(sf = 300, children = 10, step = 0);
CALL dbgen(sf = 300, children = 10, step = 1);
...
CALL dbgen(sf = 300, children = 10, step = 9);
生成测试数据
使用dbgen函数最简单的调用方式,执行sf=1 测试数据
CALL dbgen(sf = 1);
执行查询
通过调用tpch()函数来执行TPC-H的查询,这个函数只有一个参数,对应TPC-H标准SQL查询号,下面的语句执行标准的第4个查询。
PRAGMA tpch(4);
┌─────────────────┬─────────────┐
│ o_orderpriority │ order_count │
│ varchar │ int64 │
├─────────────────┼─────────────┤
│ 1-URGENT │ 10594 │
│ 2-HIGH │ 10476 │
│ 3-MEDIUM │ 10410 │
│ 4-NOT SPECIFIED │ 10556 │
│ 5-LOW │ 10487 │
└─────────────────┴─────────────┘
3拷贝数据至MySQL数据库
3.1 连接至MySQL 数据库
检查扩展mysql_scanner是否安装
duckdb到MySQL的连接是通过扩展mysql_scanner支持的,duckdb为这个扩展创建了别名mysql,在连接到MySQL数据库之前,先检查这个扩展是否安装
select * from duckdb_extensions() s WHERE extension_name like '%mysql%';
┌────────────────┬─────────┬───────────┬───┬───────────┬───────────────────┬──────────────┬────────────────┐
│ extension_name │ loaded │ installed │ … │ aliases │ extension_version │ install_mode │ installed_from │
│ varchar │ boolean │ boolean │ │ varchar[] │ varchar │ varchar │ varchar │
├────────────────┼─────────┼───────────┼───┼───────────┼───────────────────┼──────────────┼────────────────┤
│ mysql_scanner │ false │ false │ … │ [mysql] │ │ │ │
├────────────────┴─────────┴───────────┴───┴───────────┴───────────────────┴──────────────┴────────────────┤
│ 1 rows 9 columns (7 shown) │
mysql_scanner扩展的loaded和installed列的值都为false,需要安装和载入这个扩展后才能连接。
安装并载入扩展mysql_scanner
D install mysql_scanner;
100% ▕████████████████████████████████████████████████████████████▏
D load mysql_scanner;
D select * from duckdb_extensions() s WHERE extension_name like '%mysql%';
┌────────────────┬─────────┬───────────┬───┬───────────┬───────────────────┬──────────────┬────────────────┐
│ extension_name │ loaded │ installed │ … │ aliases │ extension_version │ install_mode │ installed_from │
│ varchar │ boolean │ boolean │ │ varchar[] │ varchar │ varchar │ varchar │
├────────────────┼─────────┼───────────┼───┼───────────┼───────────────────┼──────────────┼────────────────┤
│ mysql_scanner │ true │ true │ … │ [mysql] │ 6c944ea │ REPOSITORY │ core │
├────────────────┴─────────┴───────────┴───┴───────────┴───────────────────┴──────────────┴────────────────┤
│ 1 rows 9 columns (7 shown) │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────┘
连接MySQL数据库
duckdb有多种方式可以连接至MySQL数据库,这里使用ATTACH命令连接,
ATTACH 'host=192.168.56.101 user=root password=123456 port=3307 database=tcph' AS mysqldb (TYPE mysql);
----切换至MySQL数据库
use mysqldb;
----看一下现在MySQL数据库内的表
show tables;
┌─────────┐
│ name │
│ varchar │
├─────────┤
│ 0 rows │
└─────────┘
3.2 拷贝TPC-H测试数据至MySQL
使用copy命令可以将duckdb数据库的内容拷贝至MySQL数据库,对于大数据量,拷贝的时间可能会很长,需要耐心等待。
copy from database memory to mysqldb; 100% ▕████████████████████████████████████████████████████████████
3.3 登陆MySQL数据库,查看拷入的数据
SELECT TABLE_SCHEMA,TABLE_NAME,TABLE_TYPE,ENGINE,TABLE_ROWS,AVG_ROW_LENGTH,CREATE_TIME from information_schema.tables where table_schema='tpch';
TABLE_SCHEMA|TABLE_NAME|TABLE_TYPE|ENGINE|TABLE_ROWS|AVG_ROW_LENGTH|CREATE_TIME |
------------+----------+----------+------+----------+--------------+-------------------+
tpch |customer |BASE TABLE|InnoDB| 148267| 209|2025-03-19 07:33:24|
tpch |lineitem |BASE TABLE|InnoDB| 2839441| 147|2025-03-19 07:33:24|
tpch |nation |BASE TABLE|InnoDB| 25| 655|2025-03-19 07:33:24|
tpch |orders |BASE TABLE|InnoDB| 0| 0|2025-03-19 07:33:24|
tpch |part |BASE TABLE|InnoDB| 198384| 161|2025-03-19 07:33:25|
tpch |partsupp |BASE TABLE|InnoDB| 792006| 198|2025-03-19 07:33:25|
tpch |region |BASE TABLE|InnoDB| 5| 3276|2025-03-19 07:33:25|
tpch |supplier |BASE TABLE|InnoDB| 9996| 263|2025-03-19 07:33:26|
3.4 断开至MySQL数据库的连接
使用detach命令断开至MySQL数据库的连接
detach mysqldb;
Binder Error: Cannot detach database "mysqldb" because it is the default database. Select a different database using `USE` to allow detaching this database
--报错!因为要断开的数据库连接是当前默认数据库
use memory;
detach mysqldb;
show databases;
┌───────────────┐
│ database_name │
│ varchar │
├───────────────┤
│ memory │
└───────────────┘
--将默认数据库切换至duckdb内存数据库memory,后断开连接成功。
4 写在后面
使用duckdb生成TPC-H测试集确实简单,duckdb也提供了tpc-ds扩展,可以一条命令生成TPC-DS测试数据集,用法和tpch扩展差不多,比起TPC-H基准来说,TPC-DS 更加复杂和全面,更加接近真实场景。另外,duckdb目前支持连接MySQL数据库和postgresql数据库。
duckdb生成的数据不包括索引和外键,如有必要,可以使用TPC-H压缩包里的相应SQL脚本创建。




