对标SQLite的DuckDB怎么样?

第一次对DuckDB有印象是分析SIGMOD2019年的论文,DuckDB 有4页的pdf文档介绍:

997a97959195cd50317bc0042b8a37e0.png

然后是2020年的CIDR的论文:

4d4c6ed74b3281ce7155661ff5b609b0.png

当时对DuckDB也没有放在心上。

近期技术圈里有人在分析DuckDB和PostgreSQL的结合,没想到3年左右,DuckDB发展的这么快。趁着国庆长假,抽点时间对DuckDB进行分析,以帮助大家在数据库选型时多一个选择。

DuckDB是一个嵌入式的OLAP分析引擎,定位为高性能,高可靠和方便使用的数据库系统。DuckDB提供丰富的SQL,支持任意和嵌入的关联子查询,窗口函数,字符集排序规则(collations),复杂的类型(数组,结构)。DuckDB系统开源,license为MIT,比较友好。背后支撑的商业公司为DuckDB Labs。

DuckDB对标SQLite,都是嵌入式数据库。SQLite是嵌入式的OLTP,而DuckDB是嵌入式OLAP。

DuckDB概览:

6bf764fbe6a0ca3d89962945bd962b71.png

核心特性:

  • 列存

  • 向量式计算

  • 支持ACID

  • 通过MVCC方式来支持并发控制

  • WASM (web assembly)

  • ART索引

  • 支持基于成本和规则的优化

  • 采用PostgreSQL parser

另外,DuckDB操作简单,编译和运行时无其他外部依赖。

丰富的外部接口,目前支持Python,R,Java,node.js,Julia,C/C++,CLI,ODBC接口。安装和使用都比较简单,以Python环境为例:

9cda3d4c3c4bb439c1226947fda31a98.png

SQL处理采用流水线式的处理模式:

4be7bc3d3860cbd7c597e1682e0c6416.png

其中解析器Parser是采用PostgreSQL的解析器,并做了裁剪。

通过SQLite兼容层,来允许现有的应用从SQLite切换到DuckDB。

DuckDB采用向量化的解释执行引擎,而没有采用JIT(Just-in-Time)编译模式,是因为考虑可移植性。JIT依赖其他大量的编译库,例如LLVM。DuckDB采用固定最大值的向量(默认是1024),例如固定长度类型,例如整数,被作为原生数组来保存,变长的值,例如字符串,被作为一个原生数组的支付窜,指向一个单独的字符串堆(string heap)。

NULL值被表达为独立的位向量(bit vector)。

执行引擎按火山模型的模式来执行查询:

089d6aa6ab6c83f5f531e82af0253a87.png

每个算子调用子算子的“GetChunk”来获取输入chuck(=set of vector 向量集)

0b1e482fae051cce5545092160063719.png

Scan算子从基表中获取数据

474f5d167cfdf86cb83a8e7bf52c92e0.png

DuckDB通过MVCC来提供ACID兼容性。MVCC是基于HyPer的MVCC机制来实现的,HyPer支持OLAP/OLTP混合模式。DuckDB的MVCC支持原地更新(updates data in-place),旧的数据保存在undo缓存中。采用MVCC而没有采用OCC(Optimistic Concurrency Control),主要是考虑后续DuckDB的并发更新的场景。

存储引擎方面,DuckDB采用读优化的数据块的存储布局。

f676051543a721ca863d7048ea820294.png

93d11aaac6303a9f0c0add09a813940d.png

逻辑表被水平分为列的多个数据块,物理上支持轻量级的压缩,数据块只是携带每个列的最大徐晓索引,以方便决定数据块与查询是否相关。另外,针对每列,数据块通过轻量级的索引来限制数据扫描的数量。

注:读优化的数据库块相关信息请参考论文

Data Blocks: Hybrid OLTP and OLAP on Compressed Storage using both Vectorization and Compilation.

数据导入导出方面,支持CVS/Parquet/S3 Parquet导入导出,例如

SELECT * FROM read_csv_auto('input.csv');

SELECT * FROM read_csv_auto('input.csv');

COPY tbl FROM 'input.csv'; 

SELECT * FROM read_parquet('input.parquet');

CREATE TABLE new_tbl AS SELECT * FROM read_parquet('input.parquet');

INSERT INTO tbl SELECT * FROM read_parquet('input.parquet');

COPY tbl FROM 'input.parquet' (FORMAT PARQUET); 

SELECT * FROM read_parquet('s3://<bucket>/<file>');

COPY <table_name> TO 's3://bucket/file.extension';

S3的操作,前提要设置好s3相关的登录信息

SET s3_region='us-east-1';

SET s3_access_key_id='<AWS access key id>';

SET s3_secret_access_key='<AWS secret access key>';

DuckDB同时支持Wasm:

310fdbff335aa481f30fb00ba525a4bd.png

Web版本的在线分析, DuckDB-Wasm的性能,目前排在第一

c4db92b7ff7a80cd974313456dab24a8.png

DuckDB-Wasm详细介绍,请参考论文:DuckDB-Wasm: Fast Analytical Processing for the Web。

DuckDB和SQLite的性能比对结果如下:

c1a179e0259fffc9859b378e078db311.png

70e4c43ea5e841208bf13d797d0f663e.png

从图可知,DuckDB的性能比SQLite好一到两个量级。

DuckDB可以通过postgres_scanner插件来访问PostgreSQL。DuckDB的PostgresSQL的扫描扩展插件,可以在PostgreSQL运行的情况下,不copy数据,即数据不在DuckDB落地,就可以进行复杂的OLAP的sql查询,并且性能还比 PostgreSQL本身运行的要快。

5f7839e0c53417538d0ab76ee704e61e.png 

22 TPC-H benchmark queries was run 5 times, and we report the median run time in seconds

同时,PostgreSQL也可以通过duckdb_fdw来访问DuckDB中的数据,详细测试用例,请参考德哥的博文:用duckdb_fdw加速PostgreSQL分析计算, 提速40倍, 真香

https://github.com/digoal/blog/blob/master/202209/20220924_01.md

duckdb_fdw 目前支持PostgreSQL 9.6, 10, 11, 12, 13 and 14

- END -

往期回顾

Service Mesh:探索分布式系统的幻觉与未来

领域驱动探索:开启架构现代化转型之路

Cloudflare 的 Kafka 之旅:万亿级消息处理实践

阿里开源的免费AI数据库工具Chat2DB++

PayPal 开源 JunoDB,支持 3500 亿次日请求的键值存储

◆ 复杂业务系统的通用架构设计

◆ K8s Pod 优雅关闭:如何避免对生产环境造成影响

◆ 云原生数据系统的设计思考

◆ 作业帮多云多活架构的探索和实践

7c77e6c5d82da412d89acc303747faf7.png

技术交流,请加微信: jiagou6688 ,备注:Java,拉你进架构群

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值