暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

2024年8款数据库数据分析能力(TPC-H)真实性能评测,真有100倍差距

NineData 2024-05-20
2803

随着数据量爆炸性的增长,数据库类产品创新层出不穷,为了更好的做技术选型参考,笔者对国内主流8种数据库进行了TPC-H(数据分析)性能评测,被测试的数据库包括:MySQL、PostgreSQL、Oracle、达梦、ClickHouse、Doris、Starrocks、DuckDB。

测试方法

TPC-H:国际数据库标准测试组织TPC推出的面向决策支持系统的数据库方法,主要用于数据分析场景性能评测,TPC-H总共需要运行22条数据分析型SQL。本次测试属于TPC-H自由测试,仅测试查询SQL,没有执行更新和事务。

数据集:TPC-H v3.0.1测试数据集,200GB(非报告标准size)。

计时方法:统计每条SQL执行时间,全部累加。设置SQL最长执行时间为300秒(5分钟),如果执行出错或者超时,则本条SQL时间按600秒计算。

测试硬件

为了公平起见,本次TPC-H测试使用了完全相同的硬件,所有产品都是单机部署重点是测试各个产品的单机处理能力。

1台阿里云ECSi4r.4xlarge
  • 处理器:16核2.7 GHz主频的Intel (®) Xeon (®) 可扩展处理器(Ice Lake ),

  • 内存:128GB

  • 硬盘:1块本地Nvme SSD,空间894GB

  • 操作系统:CentOS7.9

测试结论

排名

数据库

运行时间

单位:秒

总结

1

Doris

v2.1.2

97.97

整体表现非常优秀,轻松完成所有任务

2

Starrocks

v3.2.6

106.57

整体表现非常优秀,轻松完成所有任务

3

DuckDB

v0.10.2

119.11

整体表现非常优秀,轻松完成所有任务,作为一个后起新秀,嵌入式的OLAP数据库,表现非常出色

4

Oracle

19c

1245.74

完成所有任务,性能中等,表现很稳定,不会出现内存不足的现象。

5

ClickHouse

2024.04

2370.76

完成20个任务,数据导入非常快,单表查询表现出了优秀的性能力,两表Join以上性能急剧下滑,复杂查询容易出现内存不足而运行出错

6

PostgreSQL

v15.7

3527.1

完成19个任务,普遍性能不高,算法细节实现和Oracle还有差距,可以应用于简单的HTAP场景

7

达梦V8

202404


8851.57

完成11个查询SQL,整体性能不高,HASH JOIN内存控制还有待提升,容易出现内存不足导致SQL执行出错

8

MySQL

v8.0.32

12641.84

22个任务仅完成1个,完全不适合数据分析



接下来详细描述TPC-H测试方法和8种数据库的测试成绩


TPC-H数据模型简介

TPC-H主要模拟供应商和采购商之间的订单交易,模型总共8张表

  • region:区域表,固定5条记录
  • nation:国家表,固定25条记录
  • supplier:供应商表,数据量因子*10000条记录
  • customer:客户表,数据量因子*150000条记录
  • part:商品表,数据量因子*200000条记录
  • partsupp:供应商物件表:数据量因子*800000条记录
  • orders:订单表,数据量因子*1500000条记录
  • lineitem:订单明细表,数据量因子*6000000条记录(最大的表,占总数据率70%)
TPC-H测试的数据量大小可以任意指定,本次测试采用了200GB的规模,最大的lineitem表数据量约12亿条(200*6000000)。

模型建表

以下是MySQL语法参考,其他数据库可以根据语法修改

    create database tpch;
    use tpch;


    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;
    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,
    PRIMARY KEY (`l_orderkey`,`l_linenumber`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
    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;
    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 ;
    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;
    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;
    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;
    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;


    TPC-H 评测SQL简介

    TPC-H标准共有22条查询SQL,主要考验数据库的如下数据分析能力:
    • 多表Join

    • 子查询

    • 分组汇总(Group By,SUM)

    • 过滤计算(like模糊查询,Case when等)

    • 视图关联查询

    以TPC-H第21号SQL举例,一条SQL包括了多表关联、子查询、Group by、Order By几种数据分析中常见的运算:

      #TPC-H 21号SQL
      select
      s_name,
      count(*) as numwait
      from
      supplier,
      lineitem l1,
      orders,
      nation
      where
      s_suppkey = l1.l_suppkey
      and o_orderkey = l1.l_orderkey
      and o_orderstatus = 'F'
      and l1.l_receiptdate > l1.l_commitdate
      and exists (
      select
      *
      from
      lineitem l2
      where
      l2.l_orderkey = l1.l_orderkey
      and l2.l_suppkey <> l1.l_suppkey
      )
      and not exists (
      select
      *
      from
      lineitem l3
      where
      l3.l_orderkey = l1.l_orderkey
      and l3.l_suppkey <> l1.l_suppkey
      and l3.l_receiptdate > l3.l_commitdate
      )
      and s_nationkey = n_nationkey
      and n_name = 'RUSSIA'
      group by
      s_name
      order by
      numwait desc,
          s_name;


      tpc-h完整的22条sql可以参考dbgen工具包内容,不同的数据库需要根据语法特性微调。


      测试数据生成

      TPC-H官方提供了测试数据集构建标准程序,下载地址,下载后可以直接编译运行

        https://www.tpc.org/TPC_Documents_Current_Versions/download_programs/tools-download-request5.asp?bm_type=TPC-H&bm_vers=3.0.1&mode=CURRENT-ONLY
          cd dbgen
          #从模版中创建编译需要用的makefile
          cp makefile.suit makefile


          配置makefile内容

          CC=gcc,DATABASE=ORACLE,MACHINE=LINUX,WORKLOAD=TPCH,具体参考如下:

            ## CHANGE NAME OF ANSI COMPILER HERE
            ################
            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=ORACLE
            MACHINE = LINUX
            WORKLOAD = TPCH

              # 执行编译,生成dbgen可以执行文件
              make

              接下来可以用dbgen生成测试数据集,dbgen有非常多的参数,可以根据需要灵活使用,如果是100GB以内的小数据量,可以直接单线程一键生成

                # -s后面跟上数据集大小,单位是GB
                ./dbgen -s 100

                dbgen执行完成后,在目录下会产生以下数据文件,都是csv格式,字段间分隔符是"|"

                  customer.tbl
                  nation.tbl
                  region.tbl
                  supplier.tbl
                  part.tbl
                  partsupp.tbl
                  lineitem.tbl
                  orders.tbl

                  如果超过100GB的数据量,建议几个大表并行生成数据,尤其是订单和明细表 orders,lineitem这个两个大表,如下:-T 表示单独生成某个表的数据,-C表示计划分割为几个文件,-S表示当前生成第几份数据,通过分割文件可以并行生成数据,提升效率,后面导入到数据库也可以直接并行加速。

                    ./dbgen -s 200 -T o -C 10 -S 1 &
                    ./dbgen -s 200 -T o -C 10 -S 2 &
                    ./dbgen -s 200 -T o -C 10 -S 3 &
                    ./dbgen -s 200 -T o -C 10 -S 4 &
                    ./dbgen -s 200 -T o -C 10 -S 5 &
                    ./dbgen -s 200 -T o -C 10 -S 6 &
                    ./dbgen -s 200 -T o -C 10 -S 7 &
                    ./dbgen -s 200 -T o -C 10 -S 8 &
                    ./dbgen -s 200 -T o -C 10 -S 9 &
                    ./dbgen -s 200 -T o -C 10 -S 10 &


                    以下是各种数据库的测试明细

                    MySQL v8.0.32

                    导入数据

                    # 为了优化导入性能,可以做以下优化,都是危险操作,千万不要在生产数据库操作。

                      1. 关闭Binlog
                      2. 关闭REDO_LOG
                      3. 关闭Double Write

                      使用mysql的load data指令导入数据

                        load data local infile '/data/tpch3/dbgen/customer.tbl' into table customer fields terminated by '|';
                        load data local infile '/data/tpch3/dbgen/lineitem.tbl' into table lineitem fields terminated by '|';
                        load data local infile '/data/tpch3/dbgen/nation.tbl' into table nation fields terminated by '|';
                        load data local infile '/data/tpch3/dbgen/orders.tbl' into table orders fields terminated by '|';
                        load data local infile '/data/tpch3/dbgen/partsupp.tbl' into table partsupp fields terminated by '|';
                        load data local infile '/data/tpch3/dbgen/part.tbl' into table part fields terminated by '|';
                        load data local infile '/data/tpch3/dbgen/region.tbl' into table region fields terminated by '|';
                        load data local infile '/data/tpch3/dbgen/supplier.tbl' into table supplier fields terminated by '|';
                        执行TPC-H SQL(操作省略)

                        确实是小试牛刀,MySQL根本不适合TPC-H,即使设置了并行查询,但是只有在比较简单的单表SQL查询中可以,加上group by或者join后基本都只能是单线程操作,MySQL最后只完成了Q2,其他21条SQL都查询超时

                        查询语句

                        执行时间

                        Q1

                        超时

                        Q2

                        41.84

                        Q3

                        超时

                        Q4

                        超时

                        ...

                        ...

                        Q22

                        超时

                        总结:这个成绩真惨不忍睹,如果你要把MySQL用于查询分析,那基本是死翘翘。

                        PostgreSQL v15.7

                        功能最强大的开源关系型数据库PostgreSQL,看看是否能完成任务。

                        PostgreSQL可以采用copy导入csv文件,语法如下:

                          COPY customer FROM '/data/tpch3/dbgen/customer.tbl' delimiter '|' ;

                          需要注意的是TPC-H dbgen生成的csv格式最后多了一个"|",PostgreSQL COPY无法直接导入,可以在TPCH所有表增加一个临时的字段,或者用shell脚本批量把最后的"|"去除,类似下面的脚本

                            for i in `ls *.tbl`; do sed 's/|$//' $i > ${i/tbl/csv}; done

                              #大表设置并行
                              alter table LINEITEM set (parallel_workers=16);
                              alter table ORDERS set (parallel_workers=16);
                              alter table PARTSUPP set (parallel_workers=16);
                              alter table PART set (parallel_workers=16);


                              #关闭表autovacuum
                              ALTER TABLE LINEITEM SET (autovacuum_enabled = off);
                              ALTER TABLE ORDERS SET (autovacuum_enabled = off);
                              ALTER TABLE PARTSUPP SET (autovacuum_enabled = off);
                              ALTER TABLE PART SET (autovacuum_enabled = off);
                              ALTER TABLE CUSTOMER SET (autovacuum_enabled = off);
                              ALTER TABLE SUPPLIER SET (autovacuum_enabled = off);

                              执行结果

                              查询执行时间
                              Q1149.26
                              Q229.07
                              Q390.03
                              Q472.53
                              Q5102.01
                              Q655.74
                              Q777.44
                              Q887.11
                              Q9超时
                              Q1098.25
                              Q1119.69
                              Q1271.94
                              Q1363.79
                              Q1464.32
                              Q15272.28
                              Q16125.39
                              Q1794.37
                              Q18超时
                              Q1951.14
                              Q20超时
                              Q21195.04
                              Q227.72


                              总结:22条SQL,PostgreSQL执行成功19条,有3条SQL执行超时,比MySQL好了很多,对于一些HTAP场景,可以满足基本需求,超时的3条SQL都是有3张以上表的Join,PostgreSQL在并行查询性能方面算法还有待提升。

                              Oracle19c

                              老牌商业数据库,本次测试的是普通Oracle19c,没有使用Exadata,因此只使用行存模式。


                                #软件从官方下载
                                https://www.oracle.com/database/technologies/oracle-database-software-downloads.html


                                #安装手册
                                https://docs.oracle.com/en/database/oracle/oracle-database/19/ladbi/running-rpm-packages-to-install-oracle-database.html

                                  #设置表不记录log,可以加速导入
                                  alter table lineitem NOLOGGING;
                                  alter table partsupp NOLOGGING;
                                  alter table orders NOLOGGING;
                                  alter table part NOLOGGING;

                                  导入csv数据可以使用Oracle自带的sqlldr工具


                                    sqlldr userid=test/test@ORCLPDB1 control=load_tpch_customer.ctl rows=1000000 bindsize=20971520 direct=true
                                    load_tpch_customer.ctl文件示例
                                      LOAD DATA INFILE 'customer.tbl'   INTO TABLE customer TRAILING NULLCOLS (
                                      C_CUSTKEY terminated by '|',
                                      C_NAME terminated by '|',
                                      C_ADDRESS terminated by '|',
                                      C_NATIONKEY terminated by '|',
                                      C_PHONE terminated by '|',
                                      C_ACCTBAL terminated by '|',
                                      C_MKTSEGMENT terminated by '|',
                                      C_COMMENT terminated by '|'
                                      )


                                        #设置大表开启并行查询
                                        alter table LINEITEM parallel(degree 16);
                                        alter table PART parallel(degree 4);
                                        alter table CUSTOMER parallel(degree 4);
                                        alter table ORDERS parallel(degree 4);
                                        alter table PARTSUPP parallel(degree 4);


                                        #收集表统计信息,数据导入完毕后执行
                                        EXEC DBMS_STATS.GATHER_TABLE_STATS(ownname=> 'TEST',tabname=> 'LINEITEM',estimate_percent=>0.1,block_sample=> TRUE, method_opt=> 'FOR ALL COLUMNS SIZE AUTO');
                                        EXEC DBMS_STATS.GATHER_TABLE_STATS(ownname=> 'TEST',tabname=> 'PART',estimate_percent=>1,block_sample=> TRUE, method_opt=> 'FOR ALL COLUMNS SIZE AUTO');
                                        EXEC DBMS_STATS.GATHER_TABLE_STATS(ownname=> 'TEST',tabname=> 'SUPPLIER',estimate_percent=>1,block_sample=> TRUE, method_opt=> 'FOR ALL COLUMNS SIZE AUTO');
                                        EXEC DBMS_STATS.GATHER_TABLE_STATS(ownname=> 'TEST',tabname=> 'PARTSUPP',estimate_percent=>1,block_sample=> TRUE, method_opt=> 'FOR ALL COLUMNS SIZE AUTO');
                                        EXEC DBMS_STATS.GATHER_TABLE_STATS(ownname=> 'TEST',tabname=> 'CUSTOMER',estimate_percent=>1,block_sample=> TRUE, method_opt=> 'FOR ALL COLUMNS SIZE AUTO');
                                        EXEC DBMS_STATS.GATHER_TABLE_STATS(ownname=> 'TEST',tabname=> 'ORDERS',estimate_percent=>1,block_sample=> TRUE, method_opt=> 'FOR ALL COLUMNS SIZE AUTO');
                                        EXEC DBMS_STATS.GATHER_TABLE_STATS(ownname=> 'TEST',tabname=> 'NATION',estimate_percent=>1,block_sample=> TRUE, method_opt=> 'FOR ALL COLUMNS SIZE AUTO');
                                        EXEC DBMS_STATS.GATHER_TABLE_STATS(ownname=> 'TEST',tabname=> 'REGION',estimate_percent=>1,block_sample=> TRUE, method_opt=> 'FOR ALL COLUMNS SIZE AUTO');


                                        执行结果

                                        查询执行时间
                                        Q159.67
                                        Q213.64
                                        Q377.75
                                        Q464.06
                                        Q565.95
                                        Q657.43
                                        Q766.98
                                        Q867.43
                                        Q982.34
                                        Q10141.63
                                        Q119.97
                                        Q1263.82
                                        Q1341.26
                                        Q1416.67
                                        Q1559.17
                                        Q1618.37
                                        Q1729.33
                                        Q1874.68
                                        Q1971.02
                                        Q2031.64
                                        Q21127.94
                                        Q224.99


                                        总结:Oracle19c完成了所有任务,性能中等,Join表现很稳定,不会出现内存不足的现象。由于Oracle列存压缩仅在Exadata支持,本次使用的是行存模式,并不能展现出Oracle的最强能力。Oracle在大表扫描方面使用并行全表查询,硬盘性能大约3GB/s,因此需要全表访问大表lineitem(140GB)的任务,基本都是50秒以上。

                                        达梦8 v20240408

                                        达梦是老牌国产数据库,超过20年历史,以Oracle兼容性著称

                                        达梦8安装安装比较方便,可以在官网直接下(https://www.dameng.com),根据安装文档一步一步安装即可

                                        可以自带的dmfldr工具导入csv数据,语法和Oracle的sqlldr类似


                                          ./dmfldr userid=TEST/Dameng_123:5236 control=\'load_tpch_customer.ctl\' direct=true
                                          #load_tpch_customer.ctl 文件示例
                                            LOAD DATA INFILE 'customer.tbl' INTO TABLE customer (
                                            C_CUSTKEY terminated by '|',
                                            C_NAME terminated by '|',
                                            C_ADDRESS terminated by '|',
                                            C_NATIONKEY terminated by '|',
                                            C_PHONE terminated by '|',
                                            C_ACCTBAL terminated by '|',
                                            C_MKTSEGMENT terminated by '|',
                                            C_COMMENT terminated by '|'
                                            )

                                              #设置并行
                                              SP_SET_PARA_VALUE (1,'MAX_PARALLEL_DEGREE',16);

                                              执行结果

                                              查询执行时间
                                              Q1326.49
                                              Q265.59
                                              Q395.43
                                              Q4290.35
                                              Q5内存不足
                                              Q6285.07
                                              Q7内存不足
                                              Q8内存不足
                                              Q9内存不足
                                              Q10内存不足
                                              Q1120.92
                                              Q12292.27
                                              Q13超时
                                              Q14273.94
                                              Q15270.57
                                              Q1628.65
                                              Q17内存不足
                                              Q18超时
                                              Q19超时
                                              Q20超时
                                              Q21超时
                                              Q2228.78

                                              总结:22条SQL,达梦执行成功11条,另外11条SQL执行超时或出错,超时或出差的11条SQL都是有3张以上表的Join,达梦在Hash Join的内存管理方面欠佳,即使设置了内存大小,但还是很容易报全局内存不足。

                                              ClickHouse v2024.04

                                              ClickHouse是非常流行的开源列式数据仓库,由俄罗斯Yandex公司研发,目前是ClickHouse公司在推动发展。ClickHouse以惊人的单表查询能力著称,很好的弥补了大数据平台OLAP交互式分析能力。

                                              由于ClickHouse并不能执行标准TPC-H的SQL语法,所以需要在查询语法上做一些修改,具体参考如下文章

                                              https://www.cnblogs.com/syw20170419/p/16421131.html

                                              ClickHouse数据导入非常简单,可以直接使用Insert into table from infile语法,如下所示


                                                SET format_csv_delimiter = '|';
                                                INSERT INTO customer from infile '/data/tpch3/dbgen/customer.tbl' FORMAT CSV;
                                                执行结果:
                                                查询执行时间
                                                Q10.415
                                                Q27.632
                                                Q345.953
                                                Q4175.988
                                                Q5110.021
                                                Q63.691
                                                Q7112.006
                                                Q8172.344
                                                Q9内存不足
                                                Q1044.416
                                                Q114.62
                                                Q126.768
                                                Q1348.432
                                                Q146.037
                                                Q152.86
                                                Q165.08
                                                Q1728.806
                                                Q18215.036
                                                Q19118.199
                                                Q2048.293
                                                Q21内存不足
                                                Q2214.16


                                                总结:ClickHouse数据导入非常快,单线程可以到达300MB/s,总共完成20个任务,2个任务失败,单表查询表现出了优秀的性能力,两表Join以上性能急剧下滑,复杂查询容易出现内存不足而运行出错。ClickHouse有众多的使用者,遇到普通问题在网上都可以找到解决方案。

                                                Doris 2.1.2

                                                Apache Doris 是一款基于 MPP 架构的高性能、实时的分析型数据库。

                                                Apache Doris 最早是诞生于百度广告报表业务的 Palo 项目,2017 年正式对外开源,2018 年 7 月由百度捐赠给 Apache 基金会进行孵化,之后在 Apache 导师的指导下由孵化器项目管理委员会成员进行孵化和运营。2022 年 6 月,Apache Doris 成功从 Apache 孵化器毕业,正式成为 Apache 顶级项目(Top-Level Project,TLP)。目前 Apache Doris 社区已经聚集了来自不同行业数百家企业的 600 余位贡献者,并且每月活跃贡献者人数也超过 120 位。

                                                Doris 采用 MySQL 协议,高度兼容 MySQL 语法,整体上是FE(前端节点)+BE(后端计算与数据存储节点)的MPP架构,如下图所示。

                                                doris可以使用stream load的模式导入csv数据,性能可以达到200MB/s


                                                  curl  --location-trusted -u admin:admin -T data/tpch3/dbgen/customer.tbl -H "column_separator:|" -H "columns: c_custkey, c_name, c_address, c_nationkey, c_phone, c_acctbal, c_mktsegment, c_comment, temp" http://127.0.0.1:8030/api/tpch200/customer/_stream_load
                                                  #如果导入的csv文件很大,可以先设置最大导入的文件大小
                                                  curl -X POST http://127.0.0.1:8030/api/update_config?streaming_load_max_mb=10240

                                                  执行结果:

                                                  查询执行时间
                                                  Q113.22
                                                  Q20.761
                                                  Q33.731
                                                  Q43.308
                                                  Q56.293
                                                  Q60.415
                                                  Q72.212
                                                  Q83.793
                                                  Q911.499
                                                  Q106.835
                                                  Q110.709
                                                  Q120.944
                                                  Q138.835
                                                  Q140.527
                                                  Q150.803
                                                  Q161.435
                                                  Q171.929
                                                  Q1815.366
                                                  Q193.095
                                                  Q202.428
                                                  Q218.755
                                                  Q221.079


                                                  总结:Doris数据导入非常快,并且轻松完成了所有任务,本次测试内存128GB,Doris导入列式压缩后实际空间大约60GB,因此大部分请求都是在内存中可以计算完成,如果数据量更大,Doris可能会发生内存不足的现象。

                                                  Starrocks

                                                  Starrocks与Doris在早期是同一个内核引擎,也是FE+BE的架构,现在已经是独立开源产品演进。Starrocks最新版本支持存储计算完全分离的架构,可以把数据存储在S3、HDFS、MinIO等共享对象存储上,通过增加无数据的CN节点完成计算扩展,如下图所示。

                                                  本次测试采用单机FE+BE架构部署

                                                  starrocks操作与doris基本一致,可以使用stream load的模式导入csv数据,性能可以达到200MB/s


                                                    curl  --location-trusted -u admin:admin -T data/tpch3/dbgen/customer.tbl -H "column_separator:|" -H "columns: c_custkey, c_name, c_address, c_nationkey, c_phone, c_acctbal, c_mktsegment, c_comment, temp" http://127.0.0.1:8030/api/tpch200/customer/_stream_load
                                                    执行结果:
                                                    查询执行时间
                                                    Q110.42
                                                    Q20.44
                                                    Q36.02
                                                    Q44.66
                                                    Q57.99
                                                    Q60.35
                                                    Q74.58
                                                    Q84.71
                                                    Q912.76
                                                    Q107.94
                                                    Q110.73
                                                    Q121.21
                                                    Q1310.09
                                                    Q140.84
                                                    Q150.95
                                                    Q161.79
                                                    Q172.51
                                                    Q1812.03
                                                    Q193.29
                                                    Q201.26
                                                    Q2110.93
                                                    Q221.07


                                                    总结:Starrocks数据导入非常快,并且轻松完成了所有任务。

                                                    DuckDB(0.10.2)

                                                    DuckDB是2019年荷兰人发布的一个高性能的嵌入式开源分析性数据,它的定位类似面向OLAP的SQLite,非常轻巧,不需要安装,可以嵌入到多种语言中。比如在java中,只需要引入duckdb的jar包,就可以在代码里创建一个本地文件存储的duckdb数据仓库。DuckDB性能非常出色,本次测试中表现非常亮眼,一个仅15MB的小型嵌入式数据库达到了大型MPP系统的性能。

                                                    duckdb在tpc-h和tpc-ds方面都附加的插件,可以直接使用,非常方便

                                                    https://duckdb.org/docs/extensions/tpch

                                                      #安装tpch插件
                                                      INSTALL tpch;


                                                      #加载插件
                                                      LOAD tpch;


                                                      #生成200GB数据
                                                      CALL dbgen(sf = 200);


                                                      #运行具体的TPC-H任务
                                                      PRAGMA tpch(1);
                                                      PRAGMA tpch(2);
                                                      ...
                                                      PRAGMA tpch(22);

                                                      使用默认的tpc-h生成数据比较慢,也可以使用COPY语法导入使用TPC-H官方工具生成的数据,不需要知道分隔符,duckdb默认会自动识别CSV的格式,非常方便。

                                                        COPY customer FROM '/data/tpch3/dbgen/customer.tbl';

                                                        执行结果:

                                                        查询执行时间
                                                        Q15.209
                                                        Q21.417
                                                        Q33.369
                                                        Q43.051
                                                        Q53.492
                                                        Q61.006
                                                        Q715.31
                                                        Q83.995
                                                        Q98.681
                                                        Q105.756
                                                        Q111.074
                                                        Q122.548
                                                        Q1311.28
                                                        Q142.139
                                                        Q153.372
                                                        Q161.496
                                                        Q173.339
                                                        Q1821.53
                                                        Q195.679
                                                        Q202.808
                                                        Q2110.56
                                                        Q222.003

                                                        总结:整体表现非常优秀,轻松完成了所有任务,作为一个后起新秀,嵌入式的OLAP数据库,表现非常出色,如果数据库可以在单机内管理,duckdb是非常有竞争力的产品。

                                                        总结

                                                        从测试结果看:

                                                        • Starrocks、Doris、DuckDB是目前OLAP引擎中第一梯队,可以轻松处理TPC-H的任务。
                                                        • ClickHouse是非常流行的开源数据仓库,在单表查询方面比较强,但是多表关联计算能力容易较弱,并且容易发生内存不足现象。
                                                        • MySQL、PostgreSQL、达梦数据库主要还是面向OLTP场景,在本次TPC-H测试中表现欠佳。
                                                        • Oracle作为老牌数据库,测试中表现非常稳定,数据量在增加也不会出现内存不足的现象,但是由于行式存储引擎的缺陷,在性能上与列式存储引擎有巨大的差距,更适合复杂的HTAP场景。

                                                        为了公平起见,本次TPC-H测试使用了完全相同的硬件,所有产品都是单机部署,重点是测试各个产品的单机处理能力,没有测试Starrocks、Doris、ClickHouse这些MPP产品的分布式处理能力。计划在未来的工作中继续完善。

                                                        关于作者

                                                        叶正盛,NineData 创始人 &CEO,资深数据库专家,原阿里云数据库产品管理与解决方案部总经理。NineData(www.ninedata.cloud)是云原生数据管理平台,提供数据库 DevOps(SQL IDE、SQL 审核与发布、性能优化、数据安全管控)、数据复制(迁移、同步、ETL)、备份等功能,可以帮助用户更安全、高效使用数据。

                                                        参考:
                                                        https://www.tpc.org/tpch/default5.asp
                                                        https://www.tpc.org/TPC_Documents_Current_Versions/pdf/TPC-H_v3.0.1.pdf
                                                        https://www.dameng.com/DM8.html
                                                        https://en.wikipedia.org/wiki/DuckDB
                                                        https://duckdb.org/docs/data/csv/overview
                                                        https://duckdb.org/docs/extensions/tpch
                                                        https://doris.apache.org/zh-CN/docs/dev/get-starting/what-is-apache-doris/
                                                        https://doris.apache.org/zh-CN/docs/dev/benchmark/tpch
                                                        https://docs.starrocks.io/zh/docs/introduction/Architecture/
                                                        https://www.jianshu.com/p/83e670cf3ffb
                                                        https://www.postgresql.org/download/linux/redhat/
                                                        https://zhuanlan.zhihu.com/p/603728682
                                                        https://blog.csdn.net/m0_46427795/article/details/119568355
                                                        https://eco.dameng.com/document/dm/zh-cn/start/install-dm-linux-prepare.html
                                                        https://eco.dameng.com/info/products/dm8
                                                        https://www.oracle.com/database/technologies/oracle-database-software-downloads.html
                                                        https://docs.oracle.com/en/database/oracle/oracle-database/19/ladbi/running-rpm-packages-to-install-oracle-database.html
                                                        https://dev.mysql.com/doc/refman/8.0/en/load-data.html#load-data-local
                                                        https://blog.csdn.net/fd3200/article/details/122031670
                                                        https://zhuanlan.zhihu.com/p/566024607
                                                        https://developer.aliyun.com/article/700370

                                                        文章转载自NineData,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                                                        评论