RDS PostgreSQL 如何利用 DuckDB 加速报表查询

RDS PostgreSQL 利用 DuckDB 加速引擎,显著提升报表查询性能,兼顾 OLTP 和 OLAP 需求。

原文标题:一招解决数据库中报表查询慢的痛点

原文作者:阿里云开发者

冷月清谈:

传统的TP数据库如PostgreSQL在处理复杂报表时性能不足,而将数据迁移到OLAP系统又会增加运维成本。RDS PostgreSQL引入了DuckDB加速引擎,解决了这一难题。

DuckDB是一款高性能开源列式关系型数据库,专注于复杂SQL查询加速和大规模数据分析。它采用单机进程内架构,可以高效处理百列级宽表和十亿行级数据量的复杂分析。

DuckDB之所以快,是因为它在优化器、执行器、操作符和存储等各个环节都采用了最新的技术。优化器在缺少统计信息的情况下也能高效优化连接顺序;执行器采用列向量化执行和基于推送的执行模型,提高了CPU效率和并行度;操作符针对sort、hash aggregation等核心算子进行了优化;存储方面采用了列式存储。

RDS DuckDB架构通过数据同步和查询处理两个模块实现加速。数据同步模块将PostgreSQL中的行存数据转换为列存数据并同步到DuckDB;查询处理模块将分析查询路由到DuckDB执行,并将结果返回给客户端。

RDS DuckDB适用于对分析数据的时效性有要求的场景,例如定时数据批量导入的离线报表业务和实时数据分析的实时报表业务。

相比RDS PG,rds_duckdb在TPC-H测试中查询性能有极大幅度的提升,多数查询在3秒内完成,而RDS PG部分查询超过10分钟。相比ClickHouse,rds_duckdb在部分查询上也更快,并且可以使用更少的内存。此外,rds_duckdb导出的列存表具有更高的压缩比,有效节省空间。

怜星夜思:

1、DuckDB除了在PostgreSQL中使用,还有什么其他应用场景?
2、相比ClickHouse、Snowflake等OLAP数据库,DuckDB有哪些优势和劣势?
3、如何评估是否需要在现有的PostgreSQL中引入DuckDB?

原文内容

阿里妹导读


本文旨在解决传统数据库系统如PostgreSQL在处理复杂分析查询时面临的性能瓶颈问题。

背景

常见的CRM, ERP等信息管理系统都基于数据库构建。它们都是常见的TP系统,强调一致性、高并发的在线事务处理(OLTP)系统。这类系统里面有日常的数据增删改查的事务需求,也有周期性的报表需求。TP数据库如PostgreSQL在解决事务型需求时性能卓越,但在处理复杂报表的分析型需求时则表现欠佳,难以高效支持多维度聚合、大规模表关联等操作。传统方案需通过ETL将数据迁移至ClickHouse、Snowflake等专用OLAP系统,导致架构割裂、运维成本陡增。

为了提升TP系统的分析性能,RDS PosgreSQL引入DuckDB,推出了rds_duckdb加速引擎。该引擎利用PostgreSQL扩展插件接口,深度集成DuckDB,实现了一体化的实时事务处理和实时数据分析的能力,一站式满足业务的OLTP及OLAP需求。通过使用rds_duckdb可以获得与原生DuckDB几乎相同的性能,TPCH性能有10-100倍的提升。我们可以将RDS PostgreSQL中的本地表、视图、物化视图等导出为列存表,同时支持行存到列存数据的自动同步。启用分析型查询加速功能后,查询会被在duckdb中执行,非常适合实时报表等复杂分析场景。

什么是DuckDB?

DuckDB【1】【2】是一款面向嵌入式分析场景的高性能开源列式关系型数据库,专注于复杂SQL查询的加速与大规模数据分析(OLAP)。该项目由荷兰国家数学与计算机科学研究院(CWI)的 Mark Raasveldt 和 Hannes Mühleisen 主导开发,于2019年正式开源,凭借其卓越的AP性能与轻量级设计,迅速成为数据科学和边缘计算领域的热门选择,月下载量超百万次。其核心优势在于以单机进程内(in-process)架构高效处理百列级宽表及十亿行级数据量的复杂分析,例如多表关联聚合、窗口函数计算等场景。与SQLite等传统嵌入式数据库的OLTP定位不同,DuckDB深度优化列式存储、向量化执行引擎及并行计算,特别适配Python/R生态的数据分析、BI工具嵌入式加速等场景。截至2024年,其GitHub Star数已突破24.7k,社区贡献者超500人,版本迭代速度与性能优化持续领跑开源OLAP领域。

DuckDB为什么这么快?

DuckDB从优化器,执行器,操作符,和存储等各个环节都利用了业界最新的技术,并凭借强大的工程能力,实现了单机复杂查询的极致性能,超过了同类分析型数据库。这里仅对DuckDB的优化点做一个简单的概述,具体的实现细节可以参考引用文档。


优化器

在很少甚至没有统计信息的情况下,连接顺序优化器(join order optimzier)【3】通过减少连接过程中处理的中间元组数量,显著提升了多表join查询性能。具体优化点如下:

  • 通过减少多表连接时的中间结果规模,提升复杂查询的执行效率;
  • 在Join Order枚举过程中,采用高效的搜索策略,平衡探索空间与计算开销,避免传统动态规划方法的高复杂度问题;
  • 轻量化统计依赖:结合轻量级信息生成优化策略,降低对传统统计信息的依赖,适应实时分析场景。

执行器

2.1 列向量化执行(columnar-vectorized query execution engine)

DuckDB采用列向量化执行提升查询的性能。

[4]

向量化查询执行指的是数据库引擎中的一种方法,它通过批量处理数据而不是逐行处理数据来增强查询性能。这种方法通过利用现代CPU架构及其执行单指令、多数据 (SIMD) 操作的能力,提高了CPU的数据处理效率。

向量化查询执行通过将称为向量的数据块加载到CPU缓存中,并在这些数据上执行批量操作来运行。其主要特点包括:

  • 批量处理:以大块数据处理,减少与处理单个数据点相关的开销。
  • 单指令多数据 (SIMD) 优化:通过同时对多个数据点执行相同的操作来最大限度地提高效率。
  • 列式读写:仅处理查询相关的列,而不是整个数据集,从而简化操作。

2.2 基于推送的执行(push based execution)

DuckDB采用推送的执行模型提高并行度从而提升查询的性能。

基于推送的处理是一种查询处理模型,数据从底层的操作符推送到上层的操作符,整体执行的控制流是自底向上。

[5]

数据其中系统中的每个操作符自行决定是否并行执行,而不是依赖于集中执行器。DuckDB 采用这一模型,是因为原来的基于拉取(pull based execution)的向量化查询处理在添加额外操作符时遇到了挑战。基于推送的处理模型允许更灵活和高效地同时执行多个管道,提高了系统处理复杂并行性和高效操作的能力。

拉取模型往往需要在计划生成阶段就决定好并行度,DuckDB的推送模型实现了Morsel-Driven Parallelism

  • 查询被划分为多个pipeline,即执行计划可以划分为多个部分并行执行;
  • 每个操作符自行决定是否并行执行,同时操作符间的并行互相能感知到。

下图是一个三张表join的例子,左边为关系代数表达式,右边为并行化执行的过程。

[6]

推送模型还开辟了额外优化和更细粒度控制系统的可能性。其中包括使用向量缓存(Vector Cache)在操作符之间缓冲结果,直到填满向量。此外,扫描共享(Scan Sharing)涉及在有向无环图(DAG)计划中将一个子操作符的结果推送给多个父操作符。在中央位置存储状态还支持反压(Backpressure)/异步IO(Async IO),即在缓冲区满时或等待远程IO时暂停操作符执行。这种细粒度控制使得在数据库系统内能够进行更高效和优化的查询处理。

操作符(operator)优化

DuckDB针对执行器中的核心算子(包括sort,aggregationg等等)做了大量优化,以此来提升查询性能。

3.1 sort【7】【8】

DuckDB针对列存排序做了多项优化,包括利用了索引避免排序,内存与磁盘排序的切换,并行化排序,和延迟物化等等技术手段,实现了极致的排序性能。


3.2 hash aggregation【9】【10】

针对hash aggregation操作符,采用分区和并行化的优化,同时考虑内存和磁盘的交换情况,提升执行性能。

RDS DuckDB架构&性能

从以上架构图可以看到:

  • 数据同步:PG中全量行存数据导入rds_duckdb插件中,转换为列存数据,并开启增量数据同步。其中增量同步基于PG原生逻辑复制实现。

  • 查询处理:分析查询路由到rds_duckdb插件中,经过向量化并行执行算子产生查询结果,然后经过类型转换返回给客户端。

核心优势

  • HTAP性能优异:PG在OLTP方面本身具备良好性能,同时DuckDB在OLAP上性能优势明显。

  • 语法高度兼容:由于DuckDB语法解析使用了PG的语法解析器,因此rds_duckdb插件实现了对PG语法的高度兼容。

适用场景

特别适合对于业务数据已经在RDS PG中,对分析数据的时效性有要求的场景。

  • 离线分析:定时数据批量导入,离线报表业务

  • 实时分析:实时数据分析需求的场景,如实时报表。

性能对比

测试数据量:TPCH 100X。测试过程可以参考rds_duckdb官网文档中的TPC-H示例。

rds_duckdb 对比 RDS PG


在开启rds_duckdb AP加速后,相较于RDS PG,查询性能有了极大幅度的提升,下图展示了TPC-H的22条查询语句执行时间对比,rds_duckdb基本都在3s内完成,其中Q2、Q15、Q17、Q18、Q20、Q21在RDS PG中执行超过10min(测试中设置单SQL超时时间为10min)。

rds_duckdb 对比 clickhouse


图中共16条SQL,Q8、Q9因为机器内存不足运行有问题,Q19超过10min未运行出结果,Q20~Q22目前并不支持(CK TPC-H官网文档

压缩对比

下图对比了TPC-H 100X测试数据中一些表,分别在rds_duckdb、RDS PG以及开源版本ClickHouse中的大小。其中rds_duckdb导出的列存表具有最高的压缩比,可以有效节省空间。

总结

通过上面的性能和压缩数据,可以看到rds_duckdb的特点:
  • 性能优异:在复杂的查询中加速效果明显,甚至可以达到百倍、千倍。
  • 资源友好:相较于CK可以使用更少的内存完成查询。
  • 压缩比高:导出列存文件有很高的压缩比,有效节省空间。

抢先体验,参见RDS PG官网文档:AP加速引擎(rds_duckdb)https://help.aliyun.com/zh/rds/apsaradb-rds-for-postgresql/use-the-rds-duckdb-extension?spm=a2c4g.11186623.help-menu-26090.d_2_4_4.2eed3bffqCGN92

更多咨询,可以加入钉钉RDS PG插件交流群了解:103525002795 ;

参考文档

  1. DuckDB: an Embeddable Analytical Database (SIGMOD 2019 Demo)https://duckdb.org/pdf/SIGMOD2019-demo-duckdb.pdf

  2. Why DuckDB

  3. Join Order Optimization with (Almost) No Statistics (Master thesis, 2022)https://blobs.duckdb.org/papers/tom-ebergen-msc-thesis-join-order-optimization-with-almost-no-statistics.pdf

  4. In-Process Analytical Data Management with DuckDBhttps://www.infoq.com/articles/analytical-data-management-duckdb/

  5. Push versus pull-based loop fusion in query engineshttps://www.cambridge.org/core/services/aop-cambridge-core/content/view/D67AE4899E87F4B5102F859B0FC02045/S0956796818000102a.pdf/push_versus_pullbased_loop_fusion_in_query_engines.pdf

  6. Paper Reading: Morsel-Driven Parallelismhttps://frankma.me/posts/papers/morsel-driven-parallelism-numa-aware-query-evaluation/

  7. These Rows Are Made for Sorting and That's Just What We'll Do (ICDE 2023):https://duckdb.org/pdf/ICDE2023-kuiper-muehleisen-sorting.pdf

  8. Fastest Table Sort in the West – Redesigning DuckDB’s Sort:https://duckdb.org/2021/08/27/external-sorting.html

  9. Robust External Hash Aggregation in the Solid State Age (ICDE 2024):https://duckdb.org/pdf/ICDE2024-kuiper-boncz-muehleisen-out-of-core.pdf

  10. Parallel Grouped Aggregation in DuckDB:https://duckdb.org/2022/03/07/aggregate-hashtable.html


DuckDB 的优势在于轻量级、嵌入式、易于集成,并且在单机性能方面表现出色。劣势在于分布式支持较弱,不适合处理超大规模数据集。ClickHouse 和 Snowflake 则更适合大规模分布式数据仓库场景。

我觉得 DuckDB 在物联网领域很有潜力。想象一下,大量的传感器数据可以直接在边缘设备上用 DuckDB 进行实时分析,而不需要上传到云端,这样可以大大降低延迟和带宽消耗,还能保护数据隐私。

除了大家提到的,我补充一点,DuckDB也可以用做其他数据库的查询加速引擎,比如之前看到有人把它集成到MySQL中,用来加速一些复杂的分析查询,效果也不错。

补充一下,DuckDB 的社区非常活跃,迭代速度很快,新的功能和优化也在不断推出,未来可期。当然,它在某些特定功能上可能不如ClickHouse和Snowflake完善,需要根据实际需求进行选择。

DuckDB 作为一款嵌入式数据库,应用场景非常广泛。除了 PostgreSQL 的扩展,它还可以嵌入到各种应用程序中,例如 Python 和 R 的数据分析环境,提供高性能的数据处理能力。另外,它也适合在边缘计算设备上运行,进行本地数据分析。

可以先用一些复杂的报表查询语句在 PostgreSQL 和 DuckDB 中分别测试一下性能,对比一下提升幅度,再结合引入 DuckDB 的成本,就能做出更合理的评估。

DuckDB胜在轻量级,部署简单,学习成本低,适合快速上手和中小规模数据分析。ClickHouse和Snowflake功能更强大,但部署和运维更复杂,需要专业的团队来维护。

主要看你的报表查询需求的复杂度和性能要求。如果现有的报表查询速度已经无法满足业务需求,或者需要进行更复杂的实时数据分析,那么可以考虑引入 DuckDB。

我建议可以先小规模试点,比如选择一些比较重要的报表,看看引入 DuckDB 后的效果。如果效果明显,再逐步推广到其他报表。