DuckDB技术洞察
DuckDB技术洞察
Jackcao
第一次对DuckDB有印象是分析SIGMOD2019年的论文,DuckDB 有4页的pdf文档介绍:
然后是2020年的CIDR的论文:
当时对DuckDB也没有放在心上。
近期技术圈里有人在分析DuckDB和PostgreSQL的结合,没想到3年左右,DuckDB发展的这么快。趁着国庆长假,抽点时间对DuckDB进行分析,以帮助大家在数据库选型时多一个选择。
DuckDB是一个嵌入式的OLAP分析引擎,定位为高性能,高可靠和方便使用的数据库系统。DuckDB提供丰富的SQL,支持任意和嵌入的关联子查询,窗口函数,字符集排序规则(collations),复杂的类型(数组,结构)。DuckDB系统开源,license为MIT,比较友好。背后支撑的商业公司为DuckDB Labs。
DuckDB对标SQLite,都是嵌入式数据库。SQLite是嵌入式的OLTP,而DuckDB是嵌入式OLAP。
DuckDB概览:
核心特性:
- 列存
- 向量式计算
- 支持ACID
- 通过MVCC方式来支持并发控制
- WASM (web assembly)
- ART索引
- 支持基于成本和规则的优化
- 采用PostgreSQL parser
另外,DuckDB操作简单,编译和运行时无其他外部依赖。
丰富的外部接口,目前支持Python,R,Java,node.js,Julia,C/C++,CLI,ODBC接口。安装和使用都比较简单,以Python环境为例:
SQL处理采用流水线式的处理模式:
其中解析器Parser是采用PostgreSQL的解析器,并做了裁剪。
通过SQLite兼容层,来允许现有的应用从SQLite切换到DuckDB。
DuckDB采用向量化的解释执行引擎,而没有采用JIT(Just-in-Time)编译模式,是因为考虑可移植性。JIT依赖其他大量的编译库,例如LLVM。DuckDB采用固定最大值的向量(默认是1024),例如固定长度类型,例如整数,被作为原生数组来保存,变长的值,例如字符串,被作为一个原生数组的支付窜,指向一个单独的字符串堆(string heap)。
NULL值被表达为独立的位向量(bit vector)。
执行引擎按火山模型的模式来执行查询:
每个算子调用子算子的“GetChunk”来获取输入chuck(=set of vector 向量集)
Scan算子从基表中获取数据
DuckDB通过MVCC来提供ACID兼容性。MVCC是基于HyPer的MVCC机制来实现的,HyPer支持OLAP/OLTP混合模式。DuckDB的MVCC支持原地更新(updates data in-place),旧的数据保存在undo缓存中。采用MVCC而没有采用OCC(Optimistic Concurrency Control),主要是考虑后续DuckDB的并发更新的场景。
存储引擎方面,DuckDB采用读优化的数据块的存储布局。
逻辑表被水平分为列的多个数据块,物理上支持轻量级的压缩,数据块只是携带每个列的最大徐晓索引,以方便决定数据块与查询是否相关。另外,针对每列,数据块通过轻量级的索引来限制数据扫描的数量。
注:读优化的数据库块相关信息请参考论文
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:
Web版本的在线分析, DuckDB-Wasm的性能,目前排在第一
DuckDB-Wasm详细介绍,请参考论文:DuckDB-Wasm: Fast Analytical Processing for the Web。
DuckDB和SQLite的性能比对结果如下:
从图可知,DuckDB的性能比SQLite好一到两个量级。
DuckDB可以通过postgres_scanner插件来访问PostgreSQL。DuckDB的PostgresSQL的扫描扩展插件,可以在PostgreSQL运行的情况下,不copy数据,即数据不在DuckDB落地,就可以进行复杂的OLAP的sql查询,并且性能还比 PostgreSQL本身运行的要快。
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
参考
https://duckdb.org/pdf/SIGMOD2019-demo-duckdb.pdf
https://duckdb.org/pdf/CIDR2020-raasveldt-muehleisen-duckdb.pdf
https://dsdsd.da.cwi.nl/slides/dsdsd-duckdb.pdf
https://github.com/duckdb/duckdb
https://database.guide/what-is-collation-in-databases/
https://learn.microsoft.com/zh-cn/sql/t-sql/statements/collations?view=sql-server-ver16
https://www.vldb.org/pvldb/vol15/p3574-kohn.pdf
https://db.in.tum.de/teaching/ss19/moderndbs/duckdb-tum.pdf
https://dl.acm.org/doi/10.1145/2882903.2882925
https://dl.acm.org/doi/pdf/10.1145/2882903.2882925
https://shekhargulati.com/2019/12/15/the-5-minute-introduction-to-duckdb-the-sqlite-for-analytics/
https://duckdb.org/2022/09/30/postgres-scanner.html
https://github.com/digoal/blog/blob/master/202210/20221001_02.md
https://github.com/digoal/blog/blob/master/202209/20220924_01.md
https://github.com/alitrack/duckdb_fdw
- 点赞
- 收藏
- 关注作者
评论(0)