本文详细介绍了PolarDB-X 1.0的TPC-H测试设计、测试过程和测试结果。

TPC-H说明

TPC-H是业界常用的一套Benchmark,由TPC委员会制定发布,用于评测数据库的分析型查询能力。TPC-H查询包含8张数据表、22条复杂的SQL查询,大多数查询包含若干表Join、子查询和Group-by聚合等。

说明 本文的TPC-H的实现基于TPC-H的基准测试,并不能与已发布的TPC-H基准测试结果相比较,本文中的测试并不符合TPC-H基准测试的所有要求。

测试设计

  • 企业版测试环境:PolarDB-X 1.0计算资源实例企业版32C128G(单节点16C64G)、4台RDS MySQL 5.7实例(8C32G独享型)。
  • 标准版测试环境:PolarDB-X 1.0计算资源实例标准版16C64G(单节点8C32G)、4台RDS MySQL 5.7实例(4C32G 独享型)。

以下测试结果基于50 GB数据量(Scalar Factor = 50),其中主要表数据量如下:LINEITEM表约3亿行,ORDERS表7500万行,PARSUPP表4000万行。

以Q18为例,包含4张千万到亿级表的Join(含一个子查询SemiJoin)和Group-by聚合。在PolarDB-X 1.0计算资源实例上查询执行时间约11秒。

select c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice, sum(l_quantity)
from CUSTOMER, ORDERS, LINEITEM
where o_orderkey in (
        select l_orderkey
        from LINEITEM
        group by l_orderkey
        having sum(l_quantity) > 314
    )
    and c_custkey = o_custkey
    and o_orderkey = l_orderkey
group by c_name, c_custkey, o_orderkey, o_orderdate, o_totalprice
order by o_totalprice desc, o_orderdate
limit 100;

测试过程

说明 以下测试过程依赖了LoadData功能做TPC-H数据导入,该功能要求内核版本>=5.4.7-16000638。
  1. 准备压力机ECS。这是以下所有操作的基础,准备数据、运行压测等都需在这台ECS上进行。
    说明
    • 建议选择VPC网络,经典网络有可能遇到RDS某些规格没有库存。请记录VPC的ID和名称,之后所有的实例和数据都部署在这个VPC里面。
    • 建议使用最新的Debian或者CentOS镜像,防止编译时缺少依赖库。
  2. 创建PolarDB-X 1.0计算资源实例以及相应的RDS实例,注意必须和上一步骤创建的ECS在同一个VPC中。
  3. PolarDB-X 1.0计算资源实例上创建库和表,注意要指定分库分表方式,建议使用以下表结构:
    CREATE TABLE `customer` (
      `c_custkey` int(11) NOT NULL,
      `c_name` varchar(25) NOT NULL,
      `c_address` varchar(40) NOT NULL,
      `c_nationkey` int(11) NOT NULL,
      `c_phone` varchar(15) NOT NULL,
      `c_acctbal` decimal(15,2) NOT NULL,
      `c_mktsegment` varchar(10) NOT NULL,
      `c_comment` varchar(117) NOT NULL,
      PRIMARY KEY (`c_custkey`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1 dbpartition by hash(`c_custkey`) tbpartition by hash(`c_custkey`) tbpartitions 4;
    CREATE TABLE `lineitem` (
      `l_orderkey` bigint(20) NOT NULL,
      `l_partkey` int(11) NOT NULL,
      `l_suppkey` int(11) NOT NULL,
      `l_linenumber` bigint(20) 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` varchar(1) NOT NULL,
      `l_linestatus` varchar(1) NOT NULL,
      `l_shipdate` date NOT NULL,
      `l_commitdate` date NOT NULL,
      `l_receiptdate` date NOT NULL,
      `l_shipinstruct` varchar(25) NOT NULL,
      `l_shipmode` varchar(10) NOT NULL,
      `l_comment` varchar(44) NOT NULL,
      KEY `IDX_LINEITEM_SUPPKEY` (`l_suppkey`),
      KEY `IDX_LINEITEM_PARTKEY` (`l_partkey`),
      PRIMARY KEY (`l_orderkey`,`l_linenumber`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1 dbpartition by RIGHT_SHIFT(`l_orderkey`,6) tbpartition by RIGHT_SHIFT(`l_orderkey`,6) tbpartitions 4;
    CREATE TABLE `orders` (
      `o_orderkey` bigint(20) NOT NULL,
      `o_custkey` int(11) NOT NULL,
      `o_orderstatus` varchar(1) NOT NULL,
      `o_totalprice` decimal(15,2) NOT NULL,
      `o_orderdate` date NOT NULL,
      `o_orderpriority` varchar(15) NOT NULL,
      `o_clerk` varchar(15) NOT NULL,
      `o_shippriority` bigint(20) NOT NULL,
      `o_comment` varchar(79) NOT NULL,
      PRIMARY KEY (`O_ORDERKEY`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1 dbpartition by RIGHT_SHIFT(`O_ORDERKEY`,6) tbpartition by RIGHT_SHIFT(`O_ORDERKEY`,6) tbpartitions 4;
    CREATE TABLE `part` (
      `p_partkey` int(11) NOT NULL,
      `p_name` varchar(55) NOT NULL,
      `p_mfgr` varchar(25) NOT NULL,
      `p_brand` varchar(10) NOT NULL,
      `p_type` varchar(25) NOT NULL,
      `p_size` int(11) NOT NULL,
      `p_container` varchar(10) NOT NULL,
      `p_retailprice` decimal(15,2) NOT NULL,
      `p_comment` varchar(23) NOT NULL,
      PRIMARY KEY (`p_partkey`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1 dbpartition by hash(`p_partkey`) tbpartition by hash(`p_partkey`) tbpartitions 4;
    CREATE TABLE `partsupp` (
      `ps_partkey` int(11) NOT NULL,
      `ps_suppkey` int(11) NOT NULL,
      `ps_availqty` int(11) NOT NULL,
      `ps_supplycost` decimal(15,2) NOT NULL,
      `ps_comment` varchar(199) NOT NULL,
      KEY `IDX_PARTSUPP_SUPPKEY` (`PS_SUPPKEY`),
      PRIMARY KEY (`ps_partkey`,`ps_suppkey`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1 dbpartition by hash(`ps_partkey`) tbpartition by hash(`ps_partkey`) tbpartitions 4;
    CREATE TABLE `supplier` (
      `s_suppkey` int(11) NOT NULL,
      `s_name` varchar(25) NOT NULL,
      `s_address` varchar(40) NOT NULL,
      `s_nationkey` int(11) NOT NULL,
      `s_phone` varchar(15) NOT NULL,
      `s_acctbal` decimal(15,2) NOT NULL,
      `s_comment` varchar(101) NOT NULL,
      PRIMARY KEY (`s_suppkey`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1 dbpartition by hash(`s_suppkey`) tbpartition by hash(`s_suppkey`) tbpartitions 4;
    CREATE TABLE `nation` (
      `n_nationkey` int(11) NOT NULL,
      `n_name` varchar(25) NOT NULL,
      `n_regionkey` int(11) NOT NULL,
      `n_comment` varchar(152) DEFAULT NULL,
      PRIMARY KEY (`n_nationkey`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1 broadcast;
    CREATE TABLE `region` (
      `r_regionkey` int(11) NOT NULL,
      `r_name` varchar(25) NOT NULL,
      `r_comment` varchar(152) DEFAULT NULL,
      PRIMARY KEY (`r_regionkey`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1 broadcast;
  4. 准备导入数据到PolarDB-X 1.0计算资源实例。将脚本下载至压力机ECS上,下载链接:tpchData
    #解压tpchData.zip脚本
    unzip tpchData.zip
    cd tpchData-update-20210809
    #编辑conf文件
    vim params.conf

    将conf文件中最后一行的连接信息改成真实的连接信息。

    #!/bin/bash
    
    ### remote generating directory
    export remoteGenDir=./
    
    ### target path
    export targetPath=../tpch/tpchRaw
    export sourcePath=../tpch/tpchRaw
    
    ### cores per worker, default value is 1
    export coresPerWorker=1
    
    ### threads per worker, default value is 1
    export threadsPerWorker=1
    
    export hint=""
    ###如果需要测试其他规模的数量级,比如100 GB的话,则数据库名换成tpch_100g
    export insertMysql="mysql -hxxxxxxxxxx.drds.aliyuncs.com -P3306 -uxxx -pxxxxxx -Ac --local-infile tpch_50g -e"

    生成50 GB的数据。

    cd datagen
    #生成数据,这个步骤只需执行一次,后续如果有重复准备数据,可以不再重复执行
    sh generateTPCH.sh 50
    #将数据载入PolarDB-X 1.0计算资源实例
    cd ../loadTpch
    sh loadTpch.sh 50

    验证数据正确性。

    MySQL [tpch_5g]> select (select count(*) from customer) as customer_cnt,
        ->        (select count(*)  from lineitem) as lineitem_cnt,
        ->        (select count(*)  from nation) as nation_cnt,
        ->        (select count(*)  from orders) as order_cnt,
        ->        (select count(*) from part) as part_cnt,
        ->        (select count(*) from partsupp) as partsupp_cnt,
        ->        (select count(*) from region) as region_cnt,
        ->        (select count(*) from supplier) as supplier_cnt;
  5. 运行TPC-H 测试前,使用ANALYZE命令采集统计信息。
    analyze table customer;
    analyze table lineitem;
    analyze table nation;
    analyze table orders;
    analyze table part;
    analyze table partsupp;
    analyze table region;
    analyze table supplier;
  6. 进行测试。
    cd tpchData
    cd runTpch
    sh runTpch.sh
    #运行结束进入result_fixed_mget,查看各条sql成绩
    cd result_fixed_mget

测试结果

说明 PolarDB-X 1.0计算资源实例入门版不具备Parallel Query能力,不建议用于执行分析型查询。
2021051301
Query企业版(单位:秒)标准版(单位:秒)
Q0155.82111.84
Q026.1211.54
Q0315.9930
Q0417.7136.56
Q0510.8923.01
Q068.0616.76
Q0717.0934.80
Q0813.4426.09
Q0953.81101.51
Q108.7319.67
Q1118.2519.74
Q128.8018.60
Q1314.1531.33
Q1417.4942.43
Q1520.6242.79
Q162.134.15
Q171.934.07
Q1811.0122.82
Q1912.9727.61
Q2027.7749.25
Q2138.8468.08
Q225.2711.29
总计386.77754.65