基于TPC-H的DuckDB分析只读实例性能测试

2026-08-12   访问量:1010


本文通过标准的TPC-H性能测试,展示通过DuckDB分析只读实例将海量数据下的复杂分析查询性能大幅提升。

什么是DuckDB 分析型            只读          

DuckDB是一款专为嵌入式场景设计的单机OLAP(联机分析处理)数据库,其核心架构能同时兼顾性能分析与事务处理:

  • 高性能分析:列式存储可以显著加速聚合分析类查询,向量化执行引擎可高效处理批量数据。

  • 强大的事务支持:具备完整的ACID事务能力,可通过MVCC(多版本并发控制) 机制在单机环境下实现高效的并发读写操作。

DuckDB的应用场景:

  • 一体化事务处理与数据分析,加速数据分析效能

  • 提升复杂分析性能,加速慢SQL

  • 汇聚分析

  • 列存数据压缩,数据归档

RDS DuckDB分析实例以列式存储与向量化计算为核心,实现了复杂分析查询性能百倍跃升。通过列式存储压缩技术,显著降低存储成本,为企业在海量数据规模场景下提供高性价比的实时分析能力,提升企业数据驱动型决策效能。更多信息,请参见 DuckDB分析实例概览。本文将基于业界标准的TPC-H基准测试,通过一系列真实的查询场景,直观地展示并验证DuckDB分析只读实例的复杂分析查询加速能力。

准备工作

实例规格

本次测试使用了两套配置相同的RDS实例,分别代表传统的行存主库和新型的列存分析引擎。

  1. RDS MySQL主实例(对比组)

    • 系列:高可用(独享规格)

    • 内核版本:MySQL 8.0(20251231)

    • 规格: mysql.x8.4xlarge.2c(32核256 GB)

    • 存储类型:高性能云盘

  2. DuckDB分析只读实例(测试组)
    为上述主实例创建一个DuckDB分析只读实例,用于处理分析查询。本测试中使用的配置如下:

    说明                

    创建完成后,系统会自动在主实例和DuckDB分析只读实例之间建立数据同步链路。

    • 系列:高可用(独享规格)

    • 内核版本:MySQL 8.0(20260204)

    • 规格:myduckro.x8.4xlarge.1c(32核256 GB )

    • 存储类型:高性能云盘

数据集

测试采用了业界标准的TPC-H SF100基准数据集,数据总量约100 GB。数据已预先导入主实例,并自动同步至DuckDB分析只读实例。主要数据表规模如下

表名称

表中包含的数据行数

LINEITEM

600,037,902

ORDERS

150,000,000

PARTSUPP

80,000,000

PART

20,000,000

CUSTOMER

15,000,000

SUPPLIER

1,000,000

NATION

25

REGION

5

操作流程

单表查询

单表扫描及过滤

  • 测试SQL:

    SELECT * FROM lineitem WHERE L_COMMENT > 'aaaaaaaa' AND L_COMMENT < 'aaaaaaz';
  • 执行结果:

    • RDS MySQL主实例:

      Empty set (4 min 28.63 sec)
    • DuckDB分析只读实例:

      Empty set (0.50 sec)
  • 性能对比:

    实例类型

    执行耗时

    RDS MySQL主实例

    268秒

    DuckDB分析只读实例

    0.5秒

单列聚合(AGG)

  • 测试SQL:

    SELECT SUM(L_DISCOUNT) FROM lineitem;
  • 执行结果:

    • RDS MySQL主实例:

      +-----------------+
      | SUM(L_DISCOUNT) |
      +-----------------+
      | 30001636.44     |
      +-----------------+
      1 row in set (1 min 22.36 sec)
    • DuckDB分析只读实例:

      +-----------------+
      | SUM(L_DISCOUNT) |
      +-----------------+
      | 30001636.44     |
      +-----------------+
      1 row in set (0.08 sec)
  • 性能对比:

    实例类型

    执行耗时

    RDS MySQL主实例

    82秒

    DuckDB分析只读实例

    0.08秒

分组聚合(GROUP BY)

  • 测试SQL:

    SELECT L_RETURNFLAG, L_LINESTATUS, AVG(L_DISCOUNT) 
    FROM lineitem 
    WHERE L_SHIPDATE <= DATE '1998-12-01' - INTERVAL 90 DAY
    GROUP BY L_RETURNFLAG, L_LINESTATUS;
  • 执行结果:

    • RDS MySQL主实例:

      +-----------------+
      | AVG(L_DISCOUNT) |
      +-----------------+
      | 0.049998        |
      | 0.050001        |
      | 0.050002        |
      | 0.049985        |
      +-----------------+
      4 rows in set (4 min 44.40 sec)
    • DuckDB分析只读实例:

      +----------------------+
      | AVG(L_DISCOUNT) |
      +----------------------+
      | 0.050002243530929025 |
      | 0.04998528433805397  |
      | 0.04999791831562552  |
      | 0.05000130433965413  |
      +----------------------+
      4 rows in set (0.19 sec)
  • 性能对比:

    实例类型

    执行耗时

    RDS MySQL主实例

    284秒

    DuckDB分析只读实例

    0.19秒

极限深翻页(ORDER BY + LIMIT)

  • 测试SQL:

    SELECT L_ORDERKEY, SUM(L_QUANTITY) FROM lineitem GROUP BY L_ORDERKEY ORDER BY SUM(L_QUANTITY) DESC LIMIT 1000000, 100;
  • 执行结果:

    • RDS MySQL主实例:

      +------------+-----------------+
      | L_ORDERKEY | SUM(L_QUANTITY) |
      +------------+-----------------+
      |  579181024 |          244.00 |
      |        ... |             ... |
      |  579185191 |          244.00 |
      +------------+-----------------+
      100 rows in set (2 min 46.53 sec)
    • DuckDB分析只读实例:

      +------------+-----------------+
      | L_ORDERKEY | SUM(L_QUANTITY) |
      +------------+-----------------+
      |  482188741 |          244.00 |
      |         ...|             ... |
      |  143970337 |          244.00 |
      +------------+-----------------+
      
      100 rows in set (5.57 sec)
  • 性能对比:

    实例类型

    执行耗时

    RDS MySQL主实例

    166秒

    DuckDB分析只读实例

    5.57秒

多表查询及子查询

多表关联(JOIN)性能

  • 测试SQL:

    SELECT  COUNT(l3.L_DISCOUNT) FROM nation n1
      STRAIGHT_JOIN nation n2 on n1.N_NATIONKEY = n2.N_NATIONKEY
      STRAIGHT_JOIN supplier on n2.N_NATIONKEY = supplier.S_NATIONKEY and S_SUPPKEY < 2000  STRAIGHT_JOIN lineitem AS l1 on l1.L_SUPPKEY = supplier.S_SUPPKEY
      STRAIGHT_JOIN lineitem AS l2 on l1.L_ORDERKEY = l2.L_ORDERKEY and l1.L_LINENUMBER = l2.L_LINENUMBER
      STRAIGHT_JOIN lineitem AS l3 on l2.L_ORDERKEY = l3.L_ORDERKEY and l2.L_LINENUMBER = l3.L_LINENUMBER
    GROUP BY  n1.N_NAME;
  • 执行结果:

    • RDS MySQL主实例:

      +----------------------+
      | COUNT(l3.L_DISCOUNT) |
      +----------------------+
      |                 56930|
      |                  ... |
      |                 49995|
      +----------------------+
      25 rows in set (1 min 21.86 sec)
    • DuckDB分析只读实例:

      +----------------------+
      | COUNT(l3.L_DISCOUNT) |
      +----------------------+
      |                 56930|
      |                  ... |
      |                 49995|
      +----------------------+
      25 rows in set (0.67 sec)
  • 性能对比:

    实例类型

    执行耗时

    RDS MySQL主实例

    81秒

    DuckDB分析只读实例

    0.67秒

关联子查询(EXISTS)性能

  • 测试SQL:

    SELECT 
      O_ORDERPRIORITY, COUNT(*) as ORDER_COUNT 
    FROM
      orders
    WHERE
      O_ORDERDATE >= '1995-01-01' AND
      O_ORDERDATE < date_add('1995-01-01', interval '3' month) AND
      EXISTS 
        (
          SELECT * FROM lineitem WHERE L_ORDERKEY = O_ORDERKEY AND L_COMMITDATE < L_RECEIPTDATE
        )
    GROUP BY 
      O_ORDERPRIORITY
    ORDER BY
      O_ORDERPRIORITY;
  • 执行结果:

    • RDS MySQL主实例:

      +-----------------+-------------+
      | O_ORDERPRIORITY | ORDER_COUNT |
      +-----------------+-------------+
      |        1-URGENT |     1028353 |
      |          2-HIGH |     1030059 |
      |        3-MEDIUM |     1028615 |
      | 4-NOT SPECIFIED |     1028496 |
      |           5-LOW |     1029615 |
      +-----------------+-------------+
      5 rows in set (38.12 sec)
    • DuckDB分析只读实例:

      +-----------------+-------------+
      | O_ORDERPRIORITY | ORDER_COUNT |
      +-----------------+-------------+
      |        1-URGENT |     1028353 |
      |          2-HIGH |     1030059 |
      |        3-MEDIUM |     1028615 |
      | 4-NOT SPECIFIED |     1028496 |
      |           5-LOW |     1029615 |
      +-----------------+-------------+
      5 rows in set (0.31 sec)
  • 性能对比:

    实例类型

    执行耗时

    RDS MySQL主实例

    38秒

    DuckDB分析只读实例

    0.31秒

多表关联带子查询性能

  • 测试SQL:

    SELECT 
      C_NAME, C_CUSTKEY, O_ORDERKEY, O_ORDERDATE, O_TOTALPRICE, SUM(L_QUANTITY)
    FROM 
      (
        SELECT * FROM orders WHERE O_ORDERKEY IN 
          (
            SELECT L_ORDERKEY FROM lineitem GROUP BY L_ORDERKEY HAVING SUM(L_QUANTITY) > 300
          ) 
      ) AS tmp, customer, lineitem 
    WHERE 
      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;
  • 执行结果:

    • RDS MySQL主实例:

      +--------------------+-----------+------------+-------------+--------------+-----------------+
      | C_NAME | C_CUSTKEY | O_ORDERKEY | O_ORDERDATE | O_TOTALPRICE | SUM(L_QUANTITY) |
      +--------------------+-----------+------------+-------------+--------------+-----------------+
      |                ... |       ... |        ... |         ... |          ... |             ... |
      | Customer#000287677 |    287677 |  353124385 | 1993-06-11  |    353551.42 |          304.00 |
      | Customer#003777694 |   3777694 |  470363105 | 1997-04-06  |    349914.00 |          302.00 |
      | Customer#009446411 |   9446411 |  592379937 | 1995-12-29  |    343496.05 |          304.00 |
      +--------------------+-----------+------------+-------------+--------------+-----------------+
      6398 rows in set (2 min 29.34 sec)
    • DuckDB分析只读实例:

      +--------------------+-----------+------------+-------------+--------------+-----------------+
      | C_NAME | C_CUSTKEY | O_ORDERKEY | O_ORDERDATE | O_TOTALPRICE | SUM(L_QUANTITY) |
      +--------------------+-----------+------------+-------------+--------------+-----------------+
      |                ... |       ... |        ... |         ... |          ... |             ... |
      | Customer#000287677 |    287677 |  353124385 | 1993-06-11  |    353551.42 |          304.00 |
      | Customer#003777694 |   3777694 |  470363105 | 1997-04-06  |    349914.00 |          302.00 |
      | Customer#009446411 |   9446411 |  592379937 | 1995-12-29  |    343496.05 |          304.00 |
      +--------------------+-----------+------------+-------------+--------------+-----------------+
      6398 rows in set (1.20 sec)
  • 性能对比:

    实例类型

    执行耗时

    RDS MySQL主实例

    149秒

    DuckDB分析只读实例

    1.20秒

测试结论          

查询类型

RDS MySQL主实例 (耗时)

RDS DuckDB分析只读实例 (耗时)

性能提升倍数

单表扫描及过滤

268s

0.5s

约536倍

单列聚合(AGG)

82s

0.08s

约1025倍

分组聚合(GROUP BY)

284s

0.19s

约1495倍

极限深翻页

166s

5.57s

约30倍

多表关联 (JOIN)

81s

0.67s

约121倍

关联子查询

38s

0.31s

约123倍

多表关联带子查询

149s

1.20s

约124倍

测试结果表明,RDS MySQL DuckDB分析只读实例在处理各类复杂分析查询时,均展现出明显的性能优势。通过将分析负载转移至DuckDB分析只读实例,可将                          原本分钟级的慢查询缩短至秒级甚至毫秒级                                ,实现近实时的交互式数据分析,同时保障主实例的稳定性。

更多信息

免费试用

企业用户与个人用户均可免费试用DuckDB分析实例。更多细节,请参见免费试用与体验。

更多性能测试

  • 基于标准TPC-H 的全面测试结果,请参见 附录:DuckDB分析只读实例性能测试。

  • ClickHouse 官方维护的性能基准测试(Benchmark)仪表板,直观地展示并对比各种主流分析型数据库(OLAP)在处理大规模数据集时的查询速度和性能表现。更多细节,请参见 ClickBench。


热门文章
更多>