本文通过标准的TPC-H性能测试,展示通过DuckDB分析只读实例将海量数据下的复杂分析查询性能大幅提升。
DuckDB是一款专为嵌入式场景设计的单机OLAP(联机分析处理)数据库,其核心架构能同时兼顾性能分析与事务处理: 高性能分析:列式存储可以显著加速聚合分析类查询,向量化执行引擎可高效处理批量数据。 强大的事务支持:具备完整的ACID事务能力,可通过MVCC(多版本并发控制) 机制在单机环境下实现高效的并发读写操作。 DuckDB的应用场景: 一体化事务处理与数据分析,加速数据分析效能 提升复杂分析性能,加速慢SQL 汇聚分析 列存数据压缩,数据归档 RDS DuckDB分析实例以列式存储与向量化计算为核心,实现了复杂分析查询性能百倍跃升。通过列式存储压缩技术,显著降低存储成本,为企业在海量数据规模场景下提供高性价比的实时分析能力,提升企业数据驱动型决策效能。更多信息,请参见 DuckDB分析实例概览。本文将基于业界标准的TPC-H基准测试,通过一系列真实的查询场景,直观地展示并验证DuckDB分析只读实例的复杂分析查询加速能力。 本次测试使用了两套配置相同的RDS实例,分别代表传统的行存主库和新型的列存分析引擎。 RDS MySQL主实例(对比组) 系列:高可用(独享规格) 内核版本:MySQL 8.0(20251231) 规格: 存储类型:高性能云盘 DuckDB分析只读实例(测试组) 说明 创建完成后,系统会自动在主实例和DuckDB分析只读实例之间建立数据同步链路。 系列:高可用(独享规格) 内核版本:MySQL 8.0(20260204) 规格: 存储类型:高性能云盘 测试采用了业界标准的TPC-H SF100基准数据集,数据总量约100 GB。数据已预先导入主实例,并自动同步至DuckDB分析只读实例。主要数据表规模如下 表名称 表中包含的数据行数 600,037,902 150,000,000 80,000,000 20,000,000 15,000,000 1,000,000 25 5 测试SQL: 执行结果: RDS MySQL主实例: DuckDB分析只读实例: 性能对比: 实例类型 执行耗时 RDS MySQL主实例 268秒 DuckDB分析只读实例 0.5秒 测试SQL: 执行结果: RDS MySQL主实例: DuckDB分析只读实例: 性能对比: 实例类型 执行耗时 RDS MySQL主实例 82秒 DuckDB分析只读实例 0.08秒 测试SQL: 执行结果: RDS MySQL主实例: DuckDB分析只读实例: 性能对比: 实例类型 执行耗时 RDS MySQL主实例 284秒 DuckDB分析只读实例 0.19秒 测试SQL: 执行结果: RDS MySQL主实例: DuckDB分析只读实例: 性能对比: 实例类型 执行耗时 RDS MySQL主实例 166秒 DuckDB分析只读实例 5.57秒 测试SQL: 执行结果: RDS MySQL主实例: DuckDB分析只读实例: 性能对比: 实例类型 执行耗时 RDS MySQL主实例 81秒 DuckDB分析只读实例 0.67秒 测试SQL: 执行结果: RDS MySQL主实例: DuckDB分析只读实例: 性能对比: 实例类型 执行耗时 RDS MySQL主实例 38秒 DuckDB分析只读实例 0.31秒 测试SQL: 执行结果: RDS MySQL主实例: DuckDB分析只读实例: 性能对比: 实例类型 执行耗时 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。什么是DuckDB 分析型 只读
准备工作
实例规格
mysql.x8.4xlarge.2c(32核256 GB)
为上述主实例创建一个DuckDB分析只读实例,用于处理分析查询。本测试中使用的配置如下:myduckro.x8.4xlarge.1c(32核256 GB )数据集
LINEITEMORDERSPARTSUPPPARTCUSTOMERSUPPLIERNATIONREGION操作流程
单表查询
单表扫描及过滤
SELECT * FROM lineitem WHERE L_COMMENT > 'aaaaaaaa' AND L_COMMENT < 'aaaaaaz';
Empty set (4 min 28.63 sec)
Empty set (0.50 sec)
单列聚合(AGG)
SELECT SUM(L_DISCOUNT) FROM lineitem;
+-----------------+
| SUM(L_DISCOUNT) |
+-----------------+
| 30001636.44 |
+-----------------+
1 row in set (1 min 22.36 sec)
+-----------------+
| SUM(L_DISCOUNT) |
+-----------------+
| 30001636.44 |
+-----------------+
1 row in set (0.08 sec)
分组聚合(GROUP BY)
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;
+-----------------+
| AVG(L_DISCOUNT) |
+-----------------+
| 0.049998 |
| 0.050001 |
| 0.050002 |
| 0.049985 |
+-----------------+
4 rows in set (4 min 44.40 sec)
+----------------------+
| AVG(L_DISCOUNT) |
+----------------------+
| 0.050002243530929025 |
| 0.04998528433805397 |
| 0.04999791831562552 |
| 0.05000130433965413 |
+----------------------+
4 rows in set (0.19 sec)
极限深翻页(ORDER BY + LIMIT)
SELECT L_ORDERKEY, SUM(L_QUANTITY) FROM lineitem GROUP BY L_ORDERKEY ORDER BY SUM(L_QUANTITY) DESC LIMIT 1000000, 100;
+------------+-----------------+
| L_ORDERKEY | SUM(L_QUANTITY) |
+------------+-----------------+
| 579181024 | 244.00 |
| ... | ... |
| 579185191 | 244.00 |
+------------+-----------------+
100 rows in set (2 min 46.53 sec)
+------------+-----------------+
| L_ORDERKEY | SUM(L_QUANTITY) |
+------------+-----------------+
| 482188741 | 244.00 |
| ...| ... |
| 143970337 | 244.00 |
+------------+-----------------+
100 rows in set (5.57 sec)
多表查询及子查询
多表关联(JOIN)性能
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;
+----------------------+
| COUNT(l3.L_DISCOUNT) |
+----------------------+
| 56930|
| ... |
| 49995|
+----------------------+
25 rows in set (1 min 21.86 sec)
+----------------------+
| COUNT(l3.L_DISCOUNT) |
+----------------------+
| 56930|
| ... |
| 49995|
+----------------------+
25 rows in set (0.67 sec)
关联子查询(EXISTS)性能
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;+-----------------+-------------+
| 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)
+-----------------+-------------+
| 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)
多表关联带子查询性能
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;
+--------------------+-----------+------------+-------------+--------------+-----------------+
| 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)
+--------------------+-----------+------------+-------------+--------------+-----------------+
| 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)
测试结论
更多信息
免费试用
更多性能测试