---
title: "OceanBase 云数据库性能测试-TPCH 测试 - OB Cloud 云数据库 master | OceanBase 文档中心"
description: OceanBase 云数据库性能测试-TPCH 测试 本文讲介绍如何使用 TPC 官方 tpc-h 工具对 OB Cloud 云数据库 OLAP 性能进行测试。 说明 为了提升用户体验和易用性，让每一个开发者在使用数据库时都能获得较好的性能，OceanBase 数据库在 V4.0.0 版本之后，做了大量的优化工作。本…
image: https://mdn.alipayobjects.com/huamei_22khvb/afts/img/A*OSPzQ6GUQF4AAAAAQHAAAAgAeiGDAQ/original
---
切换语言

- 中文站 - 简体中文
- International - English
- 日本站 - 日本語

文档反馈![](https://mdn.alipayobjects.com/huamei_22khvb/afts/img/A*qbZXRo_94ZEAAAAAAAAAAAAADiGDAQ/original) OB Cloud 云数据库

# OceanBase 云数据库性能测试-TPCH 测试

更新时间：2026-11-11 11:39:08

本文讲介绍如何使用 TPC 官方 tpc-h 工具对 OB Cloud 云数据库 OLAP 性能进行测试。

#### 说明

为了提升用户体验和易用性，让每一个开发者在使用数据库时都能获得较好的性能，OceanBase 数据库在 V4.0.0 版本之后，做了大量的优化工作。本性能测试方法仅基于基础参数进行调优，让开发者获得较好的数据库性能体验，并不完全符合 TPC-H 标准。

## 什么是 TPC-H

TPC-H（商业智能计算测试）是美国交易处理效能委员会（TPC，Transaction Processing Performance Council）组织制定的用来模拟决策支持类应用的一个测试集。目前，学术界和工业界普遍采用 TPC-H 来评价决策支持技术方面应用的性能。这种商业测试可以全方位评测系统的整体商业计算综合能力，对厂商的要求更高，同时也具有普遍的商业实用意义，目前在银行信贷分析和信用卡分析、电信运营分析、税收分析、烟草行业决策分析中都有广泛的应用。

TPC-H 基准测试由 TPC-D（由 TPC 于 1994 年制定的标准，用于决策支持系统方面的测试基准）发展而来的。TPC-H 用 3NF 实现了一个数据仓库，共包含 8 个基本关系，其主要评价指标是各个查询的响应时间，即从提交查询到结果返回所需时间。TPC-H 基准测试的度量单位是每小时执行的查询数（QphH@size），其中 H 表示每小时系统执行复杂查询的平均次数，size 表示数据库规模的大小，它能够反映出系统在处理查询时的能力。TPC-H 是根据真实的生产运行环境来建模的，这使得它可以评估一些其他测试所不能评估的关键性能参数。总而言之，TPC 组织颁布的TPC-H 标准满足了数据仓库领域的测试需求，并且促使各个厂商以及研究机构将该项技术推向极限。

## 环境准备

- 压力机 ECS

  请准备一个 ECS，建议规格与 OBServer 规格相同，避免压力机成为瓶颈。请注意压力机 ECS 需要和 OceanBase 租户在同一 VPC 网络，且 OceanBase 集群开放了压力机 ECS 的白名单访问。
 - 创建 OceanBase 实例

     1. 创建一个 OceanBase 集群实例，操作步骤请见[创建集群实例](https://www.oceanbase.com/docs/common-oceanbase-cloud-10000000001780086)。
     2. 创建租户，根据集群资源按需设置租户规格，操作步骤请见[创建租户](https://www.oceanbase.com/docs/common-oceanbase-cloud-10000000001780107)。
     3. 创建数据库，本文以 tpchtest 为例，操作步骤请见[创建数据库](https://www.oceanbase.com/docs/common-oceanbase-cloud-1000000001018092)。
 - 安装 TPC-H Tool ：下载地址：[Download 7e965ead-8844-4efa-a275-34e35f8ab89b-tpc-h-tool.zip](http://tpc.org/TPC_Documents_Current_Versions/download_programs/tools-download-request5.asp?bm_type=TPC-H&bm_vers=3.0.0&mode=CURRENT-ONLY)

## 环境调优

测试场景说明：

在执行 TPC-H 测试前，需要对 OBServer 进行简单的设置，以发挥最大性能。

租户级参数设置：

```sql
SET GLOBAL ob_sql_work_area_percentage = 80;
SET GLOBAL ob_query_timeout = 36000000000;
SET GLOBAL ob_trx_timeout = 36000000000;
SET GLOBAL max_allowed_packet = 67108864;
SET GLOBAL parallel_servers_target = 624;

```

## 执行步骤

### 安装 TPC-H Tool

1. 下载 TPC-H Tool，详细信息请参考[TPC-H Tool 下载页面](https://www.tpc.org/tpc_documents_current_versions/download_programs/tools-download-request5.asp?bm_type=TPC-H&bm_vers=3.0.0&mode=CURRENT-ONLYY)。
 2. 下载完成后解压文件，进入 TPC-H 解压后的目录。

   ```shell
   [xxxxx@localhost ~] $ unzip 7e965ead-8844-4efa-a275-34e35f8ab89b-tpc-h-tool.zip
   [xxxxx@localhost ~] $ cd 7e965ead-8844-4efa-a275-34e35f8ab89b-tpc-h-tool

   ```
 3. 复制`makefile.suite`。

   ```shell
   [xxxxx@localhost 7e965ead-8844-4efa-a275-34e35f8ab89b-tpc-h-tool] $ cd dbgen/
   [xxxxx@localhost dbgen] $ cp makefile.suite Makefile

   ```
 4. 修改`Makefile`文件中的`CC、DATABASE、MACHINE、WORKLOAD`等参数定义。

   ```shell
   [xxxxx@localhost dbgen] $ vim Makefile
   CC      = gcc
   # Current values for DATABASE are: INFORMIX, DB2, TDAT (Teradata)
   #                                  SQLSERVER, SYBASE, ORACLE, VECTORWISE
   # Current values for MACHINE are:  ATT, DOS, HP, IBM, ICL, MVS,
   #                                  SGI, SUN, U2200, VMS, LINUX, WIN32
   # Current values for WORKLOAD are:  TPCH
   DATABASE= MYSQL
   MACHINE = LINUX
   WORKLOAD = TPCH

   ```
 5. 修改`tpcd.h`文件，并添加新的宏定义。

   ```shell
   [xxxxx@localhost dbgen] $ vim tpcd.h

   #ifdef MYSQL
   #define GEN_QUERY_PLAN ""
   #define START_TRAN "START TRANSACTION"
   #define END_TRAN "COMMIT"
   #define SET_OUTPUT ""
   #define SET_ROWCOUNT "limit %d;\n"
   #define SET_DBASE "use %s;\n"
   #endif

   ```
 6. 编译文件。

   ```shell
   make

   ```

### 生成数据

您可以根据实际环境生成 TCP-H 10G、100G 或者 1T 数据。本文以生成 100G 数据为例。

```shell
./dbgen -s 100
mkdir tpch100
mv *.tbl tpch100

```

### 生成查询 SQL

#### 说明

您可参考本节中的下述步骤生成查询 SQL 后进行调整，也可直接使用 [GitHub](https://github.com/oceanbase/obdeploy/tree/master/plugins/tpch/3.1.0/queries) 中给出的查询 SQL。 若您选择使用 GitHub 中的查询 SQL，您需将 SQL 语句中的 cpu_num 修改为实际并发数。

1. 复制`qgen`和`dists.dss` 文件至`queries`目录。

   ```shell
   cp qgen queries
   cp dists.dss queries

   ```
 2. 在`queries`目录下创建`gen.sh`脚本生成查询 SQL。

   ```shell
   [xxxxx@localhost queries] $ vim gen.sh
   #!/usr/bin/bash
   for i in {1..22}
   do  
   ./qgen -d $i -s 100 > db"$i".sql
   done

   ```
 3. 执行`gen.sh`脚本。

   ```shell
   [xxxxx@localhost queries] $ chmod +x  gen.sh
   [xxxxx@localhost queries] $ ./gen.sh

   ```
 4. 查询 SQL 进行调整。

   ```shell
   [xxxxx@localhost queries] $ dos2unix *

   ```

   调整后的查询 SQL 请参考 [GitHub](https://github.com/oceanbase/obdeploy/tree/master/plugins/tpch/3.1.0/queries) 。您需将 GitHub 给出的 SQL 语句中的`cpu_num`修改为实际并发数。建议并发数的数值与租户 CPU 总数相同，两者相等时性能最好。

   以 q1 为例，修改后的 SQL 如下：

   ```sql
   SELECT /*+ parallel(96) */   ---增加 parallel 并发执行
     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 '90' day
   GROUP BY
     l_returnflag,
     l_linestatus
   ORDER BY
     l_returnflag,
     l_linestatus;

   ```

### 新建表

创建表结构文件`create_tpch_mysql_table_part.ddl` 。

```sql
DROP TABLE IF EXISTS lineitem;
DROP TABLE IF EXISTS orders;
DROP TABLE IF EXISTS partsupp;
DROP TABLE IF EXISTS part;
DROP TABLE IF EXISTS customer;
DROP TABLE IF EXISTS supplier;
DROP TABLE IF EXISTS nation;
DROP TABLE IF EXISTS region;
DROP TABLEGROUP IF EXISTS tpch_tg_lineitem_order_group;
DROP TABLEGROUP IF EXISTS tpch_tg_partsupp_part;

CREATE TABLEGROUP IF NOT EXISTS tpch_tg_lineitem_order_group binding true partition by key 1 partitions cpu_num;
CREATE TABLEGROUP IF NOT EXISTS tpch_tg_partsupp_part binding true partition by key 1 partitions cpu_num;

DROP TABLE IF EXISTS lineitem;
CREATE TABLE lineitem (
  l_orderkey BIGINT NOT NULL,
  l_partkey BIGINT NOT NULL,
  l_suppkey INTEGER NOT NULL,
  l_linenumber INTEGER NOT NULL,
  l_quantity DECIMAL(15,2) NOT NULL,
  l_extendedprice DECIMAL(15,2) NOT NULL,
  l_discount DECIMAL(15,2) NOT NULL,
  l_tax DECIMAL(15,2) NOT NULL,
  l_returnflag char(1) DEFAULT NULL,
  l_linestatus char(1) DEFAULT NULL,
  l_shipdate date NOT NULL,
  l_commitdate date DEFAULT NULL,
  l_receiptdate date DEFAULT NULL,
  l_shipinstruct char(25) DEFAULT NULL,
  l_shipmode char(10) DEFAULT NULL,
  l_comment varchar(44) DEFAULT NULL,
  PRIMARY KEY(l_orderkey, l_linenumber))row_format = condensed
  tablegroup = tpch_tg_lineitem_order_group
  partition by key (l_orderkey) partitions cpu_num;

DROP TABLE IF EXISTS orders;
CREATE TABLE orders (
  o_orderkey bigint not null,
  o_custkey bigint not null,
  o_orderstatus char(1) default null,
  o_totalprice bigint default null,
  o_orderdate date not null,
  o_orderpriority char(15) default null,
  o_clerk char(15) default null,
  o_shippriority bigint default null,
  o_comment varchar(79) default null,
  PRIMARY KEY (o_orderkey))row_format = condensed
  tablegroup = tpch_tg_lineitem_order_group
  partition by key(o_orderkey) partitions cpu_num;

DROP TABLE IF EXISTS partsupp;
CREATE TABLE partsupp (
  ps_partkey bigint not null,
  ps_suppkey bigint not null,
  ps_availqty bigint default null,
  ps_supplycost bigint default null,
  ps_comment varchar(199) default null,
  PRIMARY KEY (ps_partkey, ps_suppkey))row_format = condensed
  tablegroup tpch_tg_partsupp_part
  partition by key(ps_partkey) partitions cpu_num;

DROP TABLE IF EXISTS part;
CREATE TABLE part (
  p_partkey bigint not null,
  p_name varchar(55) default null,
  p_mfgr char(25) default null,
  p_brand char(10) default null,
  p_type varchar(25) default null,
  p_size bigint default null,
  p_container char(10) default null,
  p_retailprice bigint default null,
  p_comment varchar(23) default null,
  PRIMARY KEY (p_partkey))row_format = condensed
  tablegroup tpch_tg_partsupp_part
  partition by key(p_partkey) partitions cpu_num;

DROP TABLE IF EXISTS customer;
CREATE TABLE customer (
  c_custkey bigint not null,
  c_name varchar(25) default null,
  c_address varchar(40) default null,
  c_nationkey bigint default null,
  c_phone char(15) default null,
  c_acctbal bigint default null,
  c_mktsegment char(10) default null,
  c_comment varchar(117) default null,
  PRIMARY KEY (c_custkey))row_format = condensed
  partition by key(c_custkey) partitions cpu_num;

DROP TABLE IF EXISTS supplier;
CREATE TABLE supplier (
  s_suppkey bigint not null,
  s_name char(25) default null,
  s_address varchar(40) default null,
  s_nationkey bigint default null,
  s_phone char(15) default null,
  s_acctbal bigint default null,
  s_comment varchar(101) default null,
  PRIMARY KEY (s_suppkey))row_format = condensed
  partition by key(s_suppkey) partitions cpu_num;

DROP TABLE IF EXISTS nation;
CREATE TABLE nation (
  n_nationkey bigint not null,
  n_name char(25) default null,
  n_regionkey bigint default null,
  n_comment varchar(152) default null,
  PRIMARY KEY (n_nationkey))row_format = condensed;

DROP TABLE IF EXISTS region;
CREATE TABLE region (
  r_regionkey bigint not null,
  r_name char(25) default null,
  r_comment varchar(152) default null,
  PRIMARY KEY (r_regionkey))row_format = condensed;

```

### 加载数据

您可以根据上述步骤生成的数据和 SQL 自行编写脚本。加载数据示例操作如下：

1. 创建加载脚本目录。

   ```shell
   [xxxxx@localhost dbgen] $ mkdir load
   [xxxxx@localhost dbgen] $ cd load
   [xxxxx@localhost load] $ cp xx/create_tpch_mysql_table_part.ddl ./

   ```
 2. 创建`load.py` 脚本。

   ```shell
   [xxxxx@localhost load] $ vim load.py

   #!/usr/bin/env python
   #-*- encoding:utf-8 -*-
   import os
   import sys
   import time
   import commands
   hostname='$oceanbase_url'  # OceanBase数据库链接地址
   port='$host_port'               #端口号
   user='$user'               # 用户名
   password='$password'           # 密码
   data_path='$path'         # 注意！！请填写压力机ECS下 tbl 所在目录
   db_name='$db_name'             # 数据库名
   # 创建表
   cmd_str='obclient -h%s -P%s -u%s@%s -p%s -D%s < create_tpch_mysql_table_part.ddl'%(hostname,port,user,tenant,password,db_name)
   result = commands.getstatusoutput(cmd_str)
   print result
   cmd_str='obclient -h%s -P%s -u%s@%s -p%s  -D%s -e "show tables;" '%(hostname,port,user,tenant,password,db_name)
   result = commands.getstatusoutput(cmd_str)
   print result
   cmd_str=""" obclient -h%s -P%s -u%s@%s -p%s -c  -D%s -e "load data /*+ parallel(80) */ local infile '%s/customer.tbl' into table customer fields terminated by '|';" """ %(hostname,port,user,tenant,password,db_name,data_path)
   result = commands.getstatusoutput(cmd_str)
   print result
   cmd_str=""" obclient -h%s -P%s -u%s@%s -p%s -c  -D%s -e "load data /*+ parallel(80) */ local infile '%s/lineitem.tbl' into table lineitem fields terminated by '|';" """ %(hostname,port,user,tenant,password,db_name,data_path)
   result = commands.getstatusoutput(cmd_str)
   print result
   cmd_str=""" obclient -h%s -P%s -u%s@%s -p%s -c -D%s -e "load data /*+ parallel(80) */ local infile '%s/nation.tbl' into table nation fields terminated by '|';" """ %(hostname,port,user,tenant,password,db_name,data_path)
   result = commands.getstatusoutput(cmd_str)
   print result
   cmd_str=""" obclient -h%s -P%s -u%s@%s -p%s -c  -D%s -e "load data /*+ parallel(80) */ local infile '%s/orders.tbl' into table orders fields terminated by '|';" """ %(hostname,port,user,tenant,password,db_name,data_path)
   result = commands.getstatusoutput(cmd_str)
   print result
   cmd_str=""" obclient -h%s -P%s -u%s@%s -p%s   -D%s -e "load data /*+ parallel(80) */ local infile '%s/partsupp.tbl' into table partsupp fields terminated by '|';" """ %(hostname,port,user,tenant,password,db_name,data_path)
   result = commands.getstatusoutput(cmd_str)
   print result
   cmd_str=""" obclient -h%s -P%s -u%s@%s -p%s -c  -D%s -e "load data /*+ parallel(80) */ local infile '%s/part.tbl' into table part fields terminated by '|';" """ %(hostname,port,user,tenant,password,db_name,data_path)
   result = commands.getstatusoutput(cmd_str)
   print result
   cmd_str=""" obclient -h%s -P%s -u%s@%s -p%s -c  -D%s -e "load data /*+ parallel(80) */ local infile '%s/region.tbl' into table region fields terminated by '|';" """ %(hostname,port,user,tenant,password,db_name,data_path)
   result = commands.getstatusoutput(cmd_str)
   print result
   cmd_str=""" obclient -h%s -P%s -u%s@%s -p%s -c  -D%s -e "load data /*+ parallel(80) */ local infile '%s/supplier.tbl' into table supplier fields terminated by '|';" """ %(hostname,port,user,tenant,password,db_name,data_path)
   result = commands.getstatusoutput(cmd_str)
   print result

   ```
 3. 加载数据。

   #### 说明

   加载数据需要安装 OBClient 客户端。

   ```shell
   python load.py
   (0,'')
   (0, 'obclient: [Warning] Using a password on the command line interface can be insecure.\nTABLE_NAME\nT1\nLINEITEM\nORDERS\nPARTSUPP\nPART\nCUSTOMER\nSUPPLIER\nNATION\nREGION')
   (0, 'obclient: [Warning] Using a password on the command line interface can be insecure.')
   (0, 'obclient: [Warning] Using a password on the command line interface can be insecure.')
   (0, 'obclient: [Warning] Using a password on the command line interface can be insecure.')
   (0, 'obclient: [Warning] Using a password on the command line interface can be insecure.')
   (0, 'obclient: [Warning] Using a password on the command line interface can be insecure.')
   (0, 'obclient: [Warning] Using a password on the command line interface can be insecure.')
   (0, 'obclient: [Warning] Using a password on the command line interface can be insecure.')

   ```
 4. 执行合并。

   ```sql
   MySQL [oceanbase]> ALTER SYSTEM major freeze;
   Query OK, 0 rows affected

   ```
 5. 查看合并是否完成。

   ```sql
   MySQL [oceanbase]> select STATUS from oceanbase.DBA_OB_MAJOR_COMPACTION;

   ```

   STATUS 从 COMPACTING 变为 IDLE 即表示合并完成。
 6. 手动收集统计信息

   ```sql
   call dbms_stats.gather_schema_stats('$db_name',degree=>96);

   ```

### 执行测试

您可以根据上述步骤生成的数据和 SQL 自行编写脚本。执行测试示例操作如下：

1. 在`queries`目录下编写测试脚本`tpch.sh` 。

   ```shell
   [xxxxx@localhost queries] $ vim tpch.sh

     #!/bin/bash
     TPCH_TEST="obclient -h $host_ip -P $host_port -utpch_100g_part@tpch_mysql  -D tpch_100g_part  -ptest -c"
     # warmup预热
     for i in {1..22}
     do
         sql1="source db${i}.sql"
         echo $sql1| $TPCH_TEST >db${i}.log  || ret=1
     done
     # 正式执行
     for i in {1..22}
     do
         starttime=`date +%s%N`
         echo `date  '+[%Y-%m-%d %H:%M:%S]'` "BEGIN Q${i}"
         sql1="source db${i}.sql"
         echo $sql1| $TPCH_TEST >db${i}.log  || ret=1
         stoptime=`date +%s%N`
         costtime=`echo $stoptime $starttime | awk '{printf "%0.2f\n", ($1 - $2) / 1000000000}'`
         echo `date  '+[%Y-%m-%d %H:%M:%S]'` "END,COST ${costtime}s"
     done

   ```
 2. 执行测试脚本。

   ```shell
   sh tpch.sh

   ```

 上一篇 下一篇 ![有帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*y6ocSqN8cqsAAAAAAAAAAAAAARQnAQ)![无帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*BG9IQJyLHF8AAAAAAAAAAAAAARQnAQ)![反馈](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*eTWdQKCRKHwAAAAAAAAAAAAAARQnAQ)[AI](https://www.oceanbase.com/obi) 咨询热线
