TPCH 标准测试集

2023-09-23 warehouse database

简介

命令行参数

常用的命令行参数有:

  • -f 覆盖存在文件。
  • -s <n> 数据规模,其中 SF=1 对应 1GB 是 Scale Factor 简写。
  • -T <c> 只生成指定的数据集,可以通过 -h 查看帮助文档。

其中 partsupporderslineitem 的数据量比较大,可以分批并发生成,通过 -C 指定分多少批,以及 -S 指定是第几批。

例如,通过如下脚本并发生成。

echo "Begin to generate data for table: lineitem"
for i in $(seq 1 "${PARALLEL}"); do
    {
        "${TPCH_DBGEN_DIR}/dbgen" -f -s "${SCALE_FACTOR}" -T L -C "${PARALLEL}" -S "${i}"
    } &
done

生成的数据有两个绑定关系,分别是 Order+LineItem 以及 Part+Supplier 两个,会同时生成对应数据。

数据更新

通过 -U 可以生成更新,只对应了 orderslineitem 两个表,还有一个是 delete 暂不清楚作用,通过 -h 参数可以看到一个简单的生成示例。

源码解析

生成数据会以 NATION 作为边界,以下会同时乘以 Scale Factor 系数,以上则只包含对应记录数。这里的 nation 和 region 信息通过 dist.dss 文件读取,其 weight 就是对应的 key 了。

tdef 定义的了表生成信息,例如默认行数、打印函数、种子函数等。

typedef struct {
   char     *name;
   char     *comment;
   DSS_HUGE  base;
   int       (*loader) ();
   long      (*gen_seed)();
   int       child;
   DSS_HUGE vtotal;
} tdef;  // dss.h
tdef tdefs[] = { // driver.c
    {"part.tbl", "part table", 200000, pr_part, sd_part, PSUPP, 0},
    {"partsupp.tbl", "partsupplier table", 200000, pr_psupp, sd_psupp, NONE, 0},
    {"supplier.tbl", "suppliers table", 10000, pr_supp, sd_supp, NONE, 0},
    {"customer.tbl", "customers table", 150000, pr_cust, sd_cust, NONE, 0},
    {"orders.tbl", "order table", 150000, pr_order, sd_order, LINE, 0},
    {"lineitem.tbl", "lineitem table", 150000, pr_line, sd_line, NONE, 0},
    {"orders.tbl", "orders/lineitem tables", 150000, pr_order_line, sd_order, LINE, 0},
    {"part.tbl", "part/partsupplier tables", 200000, pr_part_psupp, sd_part, PSUPP, 0},
    {"nation.tbl", "nation table", NATIONS_MAX, pr_nation, NO_LFUNC, NONE, 0},
    {"region.tbl", "region table", NATIONS_MAX, pr_region, NO_LFUNC, NONE, 0},
};

// 根据 dists.dss 生成具体的数据分布
typedef struct {
   long      weight;
   char     *text;
} set_member;
typedef struct {
   int         count;
   int         max;
   set_member *list;
   long       *permute;
} distribution;  // dss.h


typedef struct SEED_T {
   long table;
   DSS_HUGE value;
   DSS_HUGE usage;
   DSS_HUGE boundary;
} seed_t; // dss.h
 rnd.h 中定义了 Seed[] 数组,其定义了相关的配置参数。

main()
 |-load_dists()
 | |-read_dist() bm_utils.c
 |
 |-set_state()
 |-sd_order()
 |-sd_line()
 |-gen_tbl()
 |-pr_drange()
 |
 |-gen_tbl()
   |-row_start() rnd.c
   |-mk_nation() 生成一条 Nation 记录
   | |-dbg_text() 通过 TEXT 宏调用,实际为该函数,会先初始化部分数据
   |-mk_order() 生成一条 Order 记录
   |-tdef.loader() 执行回调函数进行保存,例如 pr_nation 函数
   | |-pr_nation()
   |   |-dbg_print() 会直接打印到文件中
   |-row_stop() rnd.c

这里以几个表为例进行跟踪。

#define  NONE           -1
#define  PART           0
#define  PSUPP          1
#define  SUPP           2
#define  CUST           3
#define  ORDER          4
#define  LINE           5
#define  ORDER_LINE     6
#define  PART_PSUPP     7
#define  NATION         8
#define  REGION         9
#define  UPDATE         10
#define  MAX_TABLE      11
#define  ONE_STREAM     1
#define  ADD_AT_END     2
// dsstypes.h
typedef struct {
    DSS_HUGE       okey;
    DSS_HUGE       partkey;
    DSS_HUGE       suppkey;
    DSS_HUGE       lcnt;
    DSS_HUGE       quantity;
    DSS_HUGE       eprice;
    DSS_HUGE       discount;
    DSS_HUGE       tax;
    char           rflag[1];
    char           lstatus[1];
    char           cdate[DATE_LEN];
    char           sdate[DATE_LEN];
    char           rdate[DATE_LEN];
    char           shipinstruct[MAXAGG_LEN + 1];
    char           shipmode[MAXAGG_LEN + 1];
    char           comment[L_CMNT_MAX + 1];
    int            clen;
} line_t;
typedef struct {
    DSS_HUGE       okey;
    DSS_HUGE       custkey;
    char           orderstatus;
    DSS_HUGE       totalprice;
    char           odate[DATE_LEN];
    char           opriority[MAXAGG_LEN + 1];
    char           clerk[O_CLRK_LEN + 1];
    long           spriority;
    DSS_HUGE       lines;
    char           comment[O_CMNT_MAX + 1];
    int            clen;
    line_t         l[O_LCNT_MAX];
} order_t;