二、TPC-H基准测试介绍
1、背景
TPC即美国事务处理效能委员会(Transaction Processing Performance Council),是一家非盈利机构,也是国际上最具权威性的高端计算器产品效能评测组织之一,被称为 “高端计算机产品竞技的国际俱乐部”。目前在国际上几乎所有 IT界知名厂商都是其会员。负责定义事务处理与数据库性能基准测试,并依据这些基准测试项目发布客观性能数据。TPC基准测试有极为严格的运行要求,并且在独立审计机构监督下进行。
TPC-H(商业智能计算测试)是TPC的重要测试标准之一,主要用来模拟真实商业的应用环境。商业智能计算测试是对现实中商用计算需求的全面模拟。它包括模拟真实商业交易数据库的动态查询,以及作为决策支持与数据库应用系统的参考。可以全方位评测系统的整体商业计算综合能力,对厂商的要求更高,同时也具有普遍的商业实用意义。
TPC-H 基准测试是由 TPC-D发展而来的。TPC-H 用 3NF 实现了一个数据仓库,共包含 8 个基本关系/表,其中表REGION和表NATION的记录数是固定的(分别为5和25),其它6个表的记录数,则随所设定的参数SF而有所不同,其数据量可以设定从 1GB~3TB 不等。有8个级别供用户选择。测试时,将22个复杂查询(SELECT)随机组成查询流,2个更新(带有INSERT和DELETE的程序段)操作组成一个更新流,查询流和更新流并发执行数据库访问,查询流数目随数据量增加而增加。TPC-H 基准测试包括 22 个查询(Q1~Q22),其主要评价指标是各个查询的响应时间,即从提交查询到结果返回所需时间.TPC-H 基准测试的度量单位是每小时执行的查询数( QphH@size),其中 H 表示每小时系统执行复杂查询的平均次数,size 表示数据库规模的大小,它能够反映出系统在处理查询时的能力.TPC-H 是根据真实的生产运行环境来建模的,这使得它可以评估一些其他测试所不能评估的关键性能参数,满足了数据仓库领域的测试需求。
在我们的实验中,为了简化操作,只测试查询,并设定的SF的值为10。表示数据量为10GB级别。8张表的E/R图(来自tpc官方文档)如下:
需要说明的是,虽然每个表都有唯一键,表之间有引用关系,TPC-H并不要求测试表定义中必须包含主键和外键定义。而允许测试的数据库自行决定。
TPC-H用来执行的查询具有下列特征:
1、具有高度复杂性;2、使用各种访问;3、是特定的;4、检查可用数据的大多数;5、各不相同;6、每次查询的参数可变。
这些查询为下列商业分析提供了答案:
价格和推广、供应和需求管理、利润和收入管理、顾客满意度研究、市场份额研究、发货管理。
因此TPC-H的22个查询涵盖了商业分析的诸方面,具有普遍性和实用性。从查询SQL语句的实际内容来看,包括符合SQL 92标准的表连接、子查询,IN、EXISTS操作,HAVING操作,GROUP BY,UNION,日期操作,也是全面地检验了数据库应付各种语句的能力。
注意:具体查询sql语句必须通过dbgen工具产生,除了限定输出记录行数的子句,不允许人工修改写法。
2、测试数据和查询语句的产生步骤
将从tpc网站下载的源代码包解压缩,从模板复制一份makefile,然后修改其中和数据库类型、操作系统类型相关的内容,执行make编译。
[oracle@redflag11012501 ~]$ cd /user1/app/oradata/tmp
[oracle@redflag11012501 tmp]$ unzip /user1/app/tpch_2_13_0.zip
Archive: /user1/app/tpch_2_13_0.zip
inflating: build.c
inflating: driver.c
inflating: bm_utils.c
inflating: rnd.c
inflating: print.c
inflating: load_stub.c
inflating: bcd2.c
inflating: speed_seed.c
inflating: text.c
....
[oracle@redflag11012501 tmp]$ cp makefile.suite makefile
[oracle@redflag11012501 tmp]$ vi makefile
...
################
## CHANGE NAME OF ANSI COMPILER HERE
################
CC = gcc
# Current values for DATABASE are: INFORMIX, DB2, TDAT (Teradata)
# SQLSERVER, SYBASE, ORACLE
# Current values for MACHINE are: ATT, DOS, HP, IBM, ICL, MVS,
# SGI, SUN, U2200, VMS, LINUX, WIN32
# Current values for WORKLOAD are: TPCH
DATABASE= ORACLE
MACHINE = LINUX
WORKLOAD = TPCH
...
[oracle@redflag11012501 tmp]$ make
chmod 755 update_release.sh
./update_release.sh 2 13 0
gcc -g -DDBNAME=\"dss\" -DLINUX -DORACLE -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64 -c -o build.o build.c
…
gcc -g -DDBNAME=\"dss\" -DLINUX -DORACLE -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64 -O -o dbgen build.o driver.o bm_utils.o rnd.o print.o load_stub.o bcd2.o speed_seed.o text.o permute.o rng64.o -lm
gcc -g -DDBNAME=\"dss\" -DLINUX -DORACLE -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64 -c -o qgen.o qgen.c
gcc -g -DDBNAME=\"dss\" -DLINUX -DORACLE -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64 -c -o varsub.o varsub.c
gcc -g -DDBNAME=\"dss\" -DLINUX -DORACLE -DTPCH -DRNG_TEST -D_FILE_OFFSET_BITS=64 -O -o qgen build.o bm_utils.o qgen.o rnd.o varsub.o text.o bcd2.o permute.o speed_seed.o rng64.o -lm
--编译完成的可执行文件
[oracle@redflag11012501 tmp]$ ls *gen
dbgen qgen
用编译好的dbgen产生测试数据,qgen产生查询语句。
[oracle@redflag11012501 tmp]$ ./dbgen -s 1
TPC-H Population Generator (Version 2.13.0)
Copyright Transaction Processing Performance Council 1994 - 2010
Do you want to overwrite ./supplier.tbl ? [Y/N]: Y
Do you want to overwrite ./customer.tbl ? [Y/N]: Y
[oracle@redflag11012501 tmp]$
[oracle@redflag11012501 tmp]$ ls -l *tbl
-rw-r--r-- 1 oracle oinstall 24346144 01-30 11:29 customer.tbl
-rw-r--r-- 1 oracle oinstall 759863287 01-30 11:29 lineitem.tbl
-rw-r--r-- 1 oracle oinstall 2224 01-30 11:29 nation.tbl
-rw-r--r-- 1 oracle oinstall 171952161 01-30 11:29 orders.tbl
-rw-r--r-- 1 oracle oinstall 118984616 01-30 11:29 partsupp.tbl
-rw-r--r-- 1 oracle oinstall 24134899 01-30 11:29 part.tbl
-rw-r--r-- 1 oracle oinstall 389 01-30 11:29 region.tbl
-rw-r--r-- 1 oracle oinstall 1409184 01-30 11:29 supplier.tbl
--qgen需要在queries目录和dists.dss文件中读取模板
[oracle@redflag11012501 tmp]$ cd queries
[oracle@redflag11012501 queries]$ ../qgen
Open failed for ./dists.dss at bm_utils.c:308
[oracle@redflag11012501 queries]$ cp ../dists.dss .
[oracle@redflag11012501 queries]$ ../qgen
-- using 1296360498 as a seed to the RNG
select
l_returnflag,
l_linestatus,
sum(l_quantity) as sum_qty,
sum(l_extendedprice) as sum_base_price,
sum(l_extendedprice * (1 - l_discount)) as sum_disc_price,
sum(l_extendedprice * (1 - l_discount) * (1 + l_tax)) as sum_charge,
avg(l_quantity) as avg_qty,
avg(l_extendedprice) as avg_price,
avg(l_discount) as avg_disc,
count(*) as count_order
from
lineitem
where
l_shipdate <= date '1998-12-01' - interval '93' day (3)
group by
l_returnflag,
l_linestatus
order by
l_returnflag,
l_linestatus;
where rownum <= -1;
从上面的输出结果可以看出,虽然指定了数据库参数,qgen产生的查询语句仍然不符合oracle的语法规则。只是添加了一个where rownum<=条件,仍然需要人工编辑,在select前面增加select * from,然后再将原始的查询作为子查询用()括起来,最后再加上where rownum条件,注意将rownum<=-1中的-1改为一个较大的正整数。另外3处需要针对Oracle语法修改的地方是:将substring函数修改为substr函数,将表别名前面的as关键字去掉,将子查询构成的别名后的列名移动到子查询的select子句。
我们在修改完成的包含22个查询语句的sql脚本前端和末尾加上如下参数,就可以方便地进行多次测试。
set autot off
spool test.log
…
pool off
exit
如果是需要强制并行查询,则采用下面的设置。无论原始表是否开启了并行,设定了什么并行度,查询优化器都采用并行查询。要查看各查询的时间,在linux下可以用grep命令:
alter session force parallel query;
…
[oracle@redflag11012602 tpch]$ cat test.log|grep "Elapsed:"
Elapsed: 00:01:06.24
Elapsed: 00:00:03.83
…
Elapsed: 00:00:19.08
Elapsed: 00:00:17.28
Elapsed: 00:00:06.06
在Windows上可以用find命令完成同样的任务,如: find "Elapsed:" test.log。