找回密码
 立即注册
首页 业界区 业界 Oracle 23ai TPC-H 测试环境部署

Oracle 23ai TPC-H 测试环境部署

劳暄美 2025-6-4 22:39:46
最近,我在 Oracle Database 23ai 上进行了 TPC-H 100GB 测试,并整理了完整的实施步骤和优化经验。如果你也想评估 Oracle 数据库在决策支持场景下的性能,可以参考我的步骤快速上手。
1. 环境准备

在开始测试之前,先介绍下本次测试环境基本情况:

  • 数据库版本:Oracle Database 23ai
  • 存储500GB 可用硬盘空间(存放临时文件、数据和索引表空间等)
  • 内存32GB
  • CPU:4核处理器(优化并行查询)
  • 操作系统:Oracle Linux 8.10(或 RHEL 兼容版本)
首先要确定在此环境成功安装了23ai数据库,安装数据库的具体步骤如果不清楚可参考《在OCI上快速静默安装23ai数据库》。
需要注意23ai只支持多租户架构,所以我这里测试是在ALFRED的租户下,在这个租户中新建一个tpch测试用户,用户的默认表空间指定为TBS_ALFRED,另外,再建立一个专门存放索引的表空间TBS_ALFRED_INDEX用于后续优化。
  1. alter session set container=ALFRED;
  2. --TABLESPACE:tbs_alfred,120G
  3. create tablespace tbs_alfred datafile '/u01/app/oracle/oradata/DEMO/alfred/tbs_alfred01.dbf' size 30G;
  4. --增加数据文件时报错,发现23ai默认创建的就是大文件表空间,那就直接resize 150G(避坑,这里大方点儿,之前我给了120G发现都不够..)
  5. ALTER DATABASE DATAFILE '/u01/app/oracle/oradata/DEMO/alfred/tbs_alfred01.dbf' RESIZE 150G;
  6. --TABLESPACE:tbs_alfred_index,60G,直接size指定
  7. create tablespace tbs_alfred_index datafile '/u01/app/oracle/oradata/DEMO/alfred/tbs_alfred_index01.dbf' size 60G;
  8. --创建测试用户tpch,并指定默认表空间为tbs_alfred,赋基本权限
  9. create user tpch identified by tpch default tablespace tbs_alfred;
  10. grant connect, resource to tpch;
  11. ALTER USER TPCH QUOTA UNLIMITED ON TBS_ALFRED;
  12. ALTER USER TPCH QUOTA UNLIMITED ON TBS_ALFRED_INDEX;
复制代码
这里创建数据文件时,同时监控看到,目前这套测试环境的IO能力并不强,极限也就是每秒200多M的写入。
为了方便后续测试,顺手配置sqlplus能够直接连接到PDB:
  1. # 配置PDB连接,更新tnsnames.ora后测试连接OK
  2. vi /u01/app/oracle/product/23.0.0/db_1/network/admin/tnsnames.ora
  3. sqlplus tpch/tpch@alfred
复制代码
2. 下载并安装 TPC-H 工具

TPC 组织官方提供 TPC-H Tools,包括:

  • DBGEN:生成测试数据(8 张表的 .tbl 数据文件)
  • QGEN:生成 SQL 查询(TPC-H 22 条查询语句)
(1) 下载 TPC-H 工具

从 TPC 官网 tpc.org 下载 TPC-H 工具包

  • https://www.tpc.org/

  • 访问 TPC-H 下载页面
  • 选择 TPC-H Tools,下载 TPC-H_Tools_v3.0.1.zip
1.png

这里需要免费注册下,系统会发给你留的邮箱发送一个下载链接,注意这个链接只能下载一次,且有时间限制:
2.png


  • 下载成功后解压:(这里用oracle用户解压,方便测试,对于压测类工具个人习惯是放在介质目录/u01/media下)
    1. unzip TPC-H_Tools_v3.0.1.zip
    2. cd TPC-H V3.0.1
    复制代码
(2) 编译 DBGEN 和 QGEN

TPC-H 需要手动配置 makefile.suite,以指定 数据库类型系统环境
修改 Makefile

编辑 dbgen 目录下的 makefile.suite,实测只需搜索并修改以下行内容即可:
  1. CC=gcc
  2. DATABASE=ORACLE
  3. MACHINE=LINUX
  4. WORKLOAD=TPCH
复制代码
编译

执行make命令进行编译:
  1. make -f makefile.suite
复制代码
成功后,当前目录下会生成:

  • dbgen(用于生成数据)
  • qgen(用于生成查询 SQL)
3. 生成 100GB TPC-H 数据

TPC-H 允许不同规模的数据集,我这里选择 100GB(Scale Factor = 100)
  1. # vi dbgen100.sh
  2. time ./dbgen -s 100 -vf
复制代码
100G也不小了,所以我这里担心时间过长,因此记录下时间,并把它放到后台执行防止期间中断:
  1. nohup sh dbgen100.sh &
复制代码
生成的数据文件包括,可使用命令 ls -lrth *.tbl 查看,直观的了解下各个表大小:
  1. [oracle@dbtest dbgen]$ ls -lrth *.tbl
  2. -rw-r--r--. 1 oracle oinstall 137M Mar  6 09:31 supplier.tbl
  3. -rw-r--r--. 1 oracle oinstall  389 Mar  6 09:31 region.tbl
  4. -rw-r--r--. 1 oracle oinstall 2.3G Mar  6 09:31 part.tbl
  5. -rw-r--r--. 1 oracle oinstall  12G Mar  6 09:31 partsupp.tbl
  6. -rw-r--r--. 1 oracle oinstall  17G Mar  6 09:31 orders.tbl
  7. -rw-r--r--. 1 oracle oinstall 2.2K Mar  6 09:31 nation.tbl
  8. -rw-r--r--. 1 oracle oinstall  75G Mar  6 09:31 lineitem.tbl
  9. -rw-r--r--. 1 oracle oinstall 2.3G Mar  6 09:31 customer.tbl
复制代码
后续优化建议:

  • 可以考虑拆分文件,dbgen支持拆分文件,这样同时可方便并行导入,本次100G的测试体量还OK,暂时就先这样。
4. 在 Oracle 数据库 23ai 中创建 TPC-H 表

TPC-H 提供了 dss.ddl,可以直接创建 8 张表
这样基础测试基本不用改dss.ddl内容,默认表创建就会在TBS_ALFRED表空间中。
第一轮测试不做优化调整类工作。
另外特别提下,脚本中的字段类型定义,比如INTEGER、VARCHAR这些,并不需要手工改为NUMBER和VARCHAR2类型,Oracle自己就会做这个工作,直接执行创建即可,执行完可以desc检查下表结构。
后续优化建议

  • 评估使用 分区表 是否可以提高查询性能,比如针对最大的几张表:lineitem、orders、partsupp,有没有合适的分区方式。
5. 使用 SQL*Loader 批量加载数据

TPC-H 生成的 .tbl 文件需要导入到 Oracle 数据库。我使用 SQL*Loader 进行高效批量导入。

  • 创建sqlldr导入所需要控制文件
    对应测试的8张表,每张表单独一个控制文件,这里我故意将控制文件名字大写,更便于区分:
  1. --1. vi NATION.ctl
  2. LOAD DATA
  3. INFILE 'nation.tbl'
  4. INTO TABLE NATION
  5. TRUNCATE
  6. FIELDS TERMINATED BY '|'
  7. (
  8.     N_NATIONKEY    INTEGER EXTERNAL,
  9.     N_NAME         CHAR(25),
  10.     N_REGIONKEY    INTEGER EXTERNAL,
  11.     N_COMMENT      CHAR(152)
  12. )
  13. --2. vi REGION.ctl
  14. LOAD DATA
  15. INFILE 'region.tbl'
  16. INTO TABLE REGION
  17. TRUNCATE
  18. FIELDS TERMINATED BY '|'
  19. (
  20.     R_REGIONKEY    INTEGER EXTERNAL,
  21.     R_NAME         CHAR(25),
  22.     R_COMMENT      CHAR(152)
  23. )
  24. --3. vi SUPPLIER.ctl
  25. LOAD DATA
  26. INFILE 'supplier.tbl'
  27. INTO TABLE SUPPLIER
  28. TRUNCATE
  29. FIELDS TERMINATED BY '|'
  30. (
  31.     S_SUPPKEY     INTEGER EXTERNAL,
  32.     S_NAME        CHAR(25),
  33.     S_ADDRESS     CHAR(40),
  34.     S_NATIONKEY   INTEGER EXTERNAL,
  35.     S_PHONE       CHAR(15),
  36.     S_ACCTBAL     DECIMAL EXTERNAL,
  37.     S_COMMENT     CHAR(101)
  38. )
  39. --4. vi PART.ctl
  40. LOAD DATA
  41. INFILE 'part.tbl'
  42. INTO TABLE PART
  43. TRUNCATE
  44. FIELDS TERMINATED BY '|'
  45. (
  46.     P_PARTKEY     INTEGER EXTERNAL,
  47.     P_NAME        CHAR(55),
  48.     P_MFGR        CHAR(25),
  49.     P_BRAND       CHAR(10),
  50.     P_TYPE        CHAR(25),
  51.     P_SIZE        INTEGER EXTERNAL,
  52.     P_CONTAINER   CHAR(10),
  53.     P_RETAILPRICE DECIMAL EXTERNAL,
  54.     P_COMMENT     CHAR(23)
  55. )
  56. --5. vi PARTSUPP.ctl
  57. LOAD DATA
  58. INFILE 'partsupp.tbl'
  59. INTO TABLE PARTSUPP
  60. TRUNCATE
  61. FIELDS TERMINATED BY '|'
  62. (
  63.     PS_PARTKEY    INTEGER EXTERNAL,
  64.     PS_SUPPKEY    INTEGER EXTERNAL,
  65.     PS_AVAILQTY   INTEGER EXTERNAL,
  66.     PS_SUPPLYCOST DECIMAL EXTERNAL,
  67.     PS_COMMENT    CHAR(199)
  68. )
  69. --6. vi CUSTOMER.ctl
  70. LOAD DATA
  71. INFILE 'customer.tbl'
  72. INTO TABLE CUSTOMER
  73. TRUNCATE
  74. FIELDS TERMINATED BY '|'
  75. (
  76.     C_CUSTKEY     INTEGER EXTERNAL,
  77.     C_NAME        CHAR(25),
  78.     C_ADDRESS     CHAR(40),
  79.     C_NATIONKEY   INTEGER EXTERNAL,
  80.     C_PHONE       CHAR(15),
  81.     C_ACCTBAL     DECIMAL EXTERNAL,
  82.     C_MKTSEGMENT  CHAR(10),
  83.     C_COMMENT     CHAR(117)
  84. )
  85. --7. vi ORDERS.ctl
  86. LOAD DATA
  87. INFILE 'orders.tbl'
  88. INTO TABLE ORDERS
  89. TRUNCATE
  90. FIELDS TERMINATED BY '|'
  91. (
  92.     O_ORDERKEY      INTEGER EXTERNAL,
  93.     O_CUSTKEY       INTEGER EXTERNAL,
  94.     O_ORDERSTATUS   CHAR(1),
  95.     O_TOTALPRICE    DECIMAL EXTERNAL,
  96.     O_ORDERDATE     DATE "YYYY-MM-DD",
  97.     O_ORDERPRIORITY CHAR(15),
  98.     O_CLERK        CHAR(15),
  99.     O_SHIPPRIORITY INTEGER EXTERNAL,
  100.     O_COMMENT      CHAR(79)
  101. )
  102. --8. vi LINEITEM.ctl
  103. LOAD DATA
  104. INFILE 'lineitem.tbl'
  105. INTO TABLE LINEITEM
  106. TRUNCATE
  107. FIELDS TERMINATED BY '|'
  108. (
  109.     L_ORDERKEY        INTEGER EXTERNAL,
  110.     L_PARTKEY         INTEGER EXTERNAL,
  111.     L_SUPPKEY         INTEGER EXTERNAL,
  112.     L_LINENUMBER      INTEGER EXTERNAL,
  113.     L_QUANTITY        DECIMAL EXTERNAL,
  114.     L_EXTENDEDPRICE   DECIMAL EXTERNAL,
  115.     L_DISCOUNT        DECIMAL EXTERNAL,
  116.     L_TAX             DECIMAL EXTERNAL,
  117.     L_RETURNFLAG      CHAR(1),
  118.     L_LINESTATUS      CHAR(1),
  119.     L_SHIPDATE        DATE "YYYY-MM-DD",
  120.     L_COMMITDATE      DATE "YYYY-MM-DD",
  121.     L_RECEIPTDATE     DATE "YYYY-MM-DD",
  122.     L_SHIPINSTRUCT    CHAR(25),
  123.     L_SHIPMODE        CHAR(10),
  124.     L_COMMENT         CHAR(44)
  125. )
复制代码

  • 运行 SQL*Loader
  1. # 1.NATION
  2. sqlldr userid=tpch/tpch@alfred control=NATION.ctl log=NATION.log bad=NATION.bad direct=true
  3. # 2.REGION
  4. sqlldr userid=tpch/tpch@alfred control=REGION.ctl log=REGION.log bad=REGION.bad direct=true
  5. # 3.SUPPLIER
  6. sqlldr userid=tpch/tpch@alfred control=SUPPLIER.ctl log=SUPPLIER.log bad=SUPPLIER.bad direct=true
  7. # 4.PART
  8. sqlldr userid=tpch/tpch@alfred control=PART.ctl log=PART.log bad=PART.bad direct=true
  9. # 5.PARTSUPP
  10. sqlldr userid=tpch/tpch@alfred control=PARTSUPP.ctl log=PARTSUPP.log bad=PARTSUPP.bad direct=true
  11. # 6.CUSTOMER
  12. sqlldr userid=tpch/tpch@alfred control=CUSTOMER.ctl log=CUSTOMER.log bad=CUSTOMER.bad direct=true
  13. # 7.ORDERS
  14. sqlldr userid=tpch/tpch@alfred control=ORDERS.ctl log=ORDERS.log bad=ORDERS.bad direct=true
  15. # 8.LINEITEM
  16. sqlldr userid=tpch/tpch@alfred control=LINEITEM.ctl log=LINEITEM.log bad=LINEITEM.bad direct=true
  17. # OPTION1:我这里因为先前只给了120G表空间,结果空间不够用,所以调整后继续加载。此外需要注意,更改LINEITEM.ctl为append,否则会清空之前记录
  18. sqlldr userid=tpch/tpch@alfred control=LINEITEM.ctl log=LINEITEM.log bad=LINEITEM.bad discard=LINEITEM.dsc direct=true skip=582854696
  19. # OPTION2:因为尚未建立任何主键唯一约束,看测试数据不是整数,误以为是数据多了一些,干脆还是全新导入,重新修改LINEITEM.ctl为truncate模式,重复步骤8,结果发现还是600037902行:
  20. sqlldr userid=tpch/tpch@alfred control=LINEITEM.ctl log=LINEITEM.log bad=LINEITEM.bad direct=true
复制代码
6. 运行 TPC-H 22 条查询

TPC-H 预定义了 22 条 SQL 查询,可以使用 qgen 生成 SQL 语句:
这里遇到一个问题,简单记录下:
  1. [oracle@dbtest dbgen]$ ./qgen -s 100 1 > query1.sql
  2. Open failed for ./1.sql at qgen.c:170
复制代码
这个报错浪费了些许时间,最后发现是要设置下变量,然后再次执行就OK:
  1. [oracle@dbtest dbgen]$ export DSS_QUERY=./queries
  2. [oracle@dbtest dbgen]$ ./qgen -s 100 1 > query1.sql
复制代码
确认OK后,直接使用下面命令,快速生成这22个query:
  1. for i in $(seq 1 22); do
  2.   ./qgen -s 100 $i > query$i.sql
  3.   echo "Generated query$i.sql"
  4. done
复制代码
然后就可以选择在 Oracle 数据库中运行,并记录执行时间:
  1. SQL>
  2. @query1
  3. @query2
  4. ...
  5. @query22
复制代码
至此,Oracle 23ai TPC-H 测试环境准备已经完成,注意此时还没有任何优化,甚至个别SQL的默认生成语法和Oracle并不兼容,后续文章将记录这些详细调整方法和一些优化技巧,敬请期待!

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册