本文詳細介紹了PolarDB-X 1.0的TPC-H測試設(shè)計、測試過程和測試結(jié)果。

TPC-H說明

TPC-H是業(yè)界常用的一套Benchmark,由TPC委員會制定發(fā)布,用于評測數(shù)據(jù)庫的分析型查詢能力。TPC-H查詢包含8張數(shù)據(jù)表、22條復(fù)雜的SQL查詢,大多數(shù)查詢包含若干表Join、子查詢和Group-by聚合等。

說明 本文的TPC-H的實現(xiàn)基于TPC-H的基準(zhǔn)測試,并不能與已發(fā)布的TPC-H基準(zhǔn)測試結(jié)果相比較,本文中的測試并不符合TPC-H基準(zhǔn)測試的所有要求。

測試設(shè)計

  • 企業(yè)版測試環(huán)境:PolarDB-X 1.0計算資源實例企業(yè)版32C128G(單節(jié)點16C64G)、4臺RDS MySQL 5.7實例(8C32G獨享型)。
  • 標(biāo)準(zhǔn)版測試環(huán)境:PolarDB-X 1.0計算資源實例標(biāo)準(zhǔn)版16C64G(單節(jié)點8C32G)、4臺RDS MySQL 5.7實例(4C32G 獨享型)。

以下測試結(jié)果基于50 GB數(shù)據(jù)量(Scalar Factor = 50),其中主要表數(shù)據(jù)量如下:LINEITEM表約3億行,ORDERS表7500萬行,PARSUPP表4000萬行。

以Q18為例,包含4張千萬到億級表的Join(含一個子查詢SemiJoin)和Group-by聚合。在PolarDB-X 1.0計算資源實例上查詢執(zhí)行時間約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數(shù)據(jù)導(dǎo)入,該功能要求內(nèi)核版本>=5.4.7-16000638。
  1. 準(zhǔn)備壓力機ECS。這是以下所有操作的基礎(chǔ),準(zhǔn)備數(shù)據(jù)、運行壓測等都需在這臺ECS上進行。
    說明
    • 建議選擇VPC網(wǎng)絡(luò),經(jīng)典網(wǎng)絡(luò)有可能遇到RDS某些規(guī)格沒有庫存。請記錄VPC的ID和名稱,之后所有的實例和數(shù)據(jù)都部署在這個VPC里面。
    • 建議使用最新的Debian或者CentOS鏡像,防止編譯時缺少依賴庫。
  2. 創(chuàng)建PolarDB-X 1.0計算資源實例以及相應(yīng)的RDS實例,注意必須和上一步驟創(chuàng)建的ECS在同一個VPC中。
  3. PolarDB-X 1.0計算資源實例上創(chuàng)建庫和表,注意要指定分庫分表方式,建議使用以下表結(jié)構(gòu):
    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. 準(zhǔn)備導(dǎo)入數(shù)據(jù)到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=""
    ###如果需要測試其他規(guī)模的數(shù)量級,比如100 GB的話,則數(shù)據(jù)庫名換成tpch_100g
    export insertMysql="mysql -hxxxxxxxxxx.drds.aliyuncs.com -P3306 -uxxx -pxxxxxx -Ac --local-infile tpch_50g -e"

    生成50 GB的數(shù)據(jù)。

    cd datagen
    #生成數(shù)據(jù),這個步驟只需執(zhí)行一次,后續(xù)如果有重復(fù)準(zhǔn)備數(shù)據(jù),可以不再重復(fù)執(zhí)行
    sh generateTPCH.sh 50
    #將數(shù)據(jù)載入PolarDB-X 1.0計算資源實例
    cd ../loadTpch
    sh loadTpch.sh 50

    驗證數(shù)據(jù)正確性。

    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命令采集統(tǒng)計信息。
    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
    #運行結(jié)束進入result_fixed_mget,查看各條sql成績
    cd result_fixed_mget

測試結(jié)果

說明 PolarDB-X 1.0計算資源實例入門版不具備Parallel Query能力,不建議用于執(zhí)行分析型查詢。
2021051301
Query企業(yè)版(單位:秒)標(biāo)準(zhǔn)版(單位:秒)
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