已加载全部内容

为什么 DuckDB 很快?

链接
分类
文章开发工具2026-06-20 04:31:00
简介

作为嵌入式的列式数据库,DuckDB 都有哪些神奇的 feature。

相似条目

笔记

Beta

本文核心主题,一款进程内分析型SQL数据库,通过避免网络序列化、采用列式压缩存储加zonemaps、向量化执行与morsel并行等机制实现单节点高速查询。文章详细拆解其SQL解析、绑定、约33个优化器 passes、物理计划管道拆分,以及直接读取Parquet/CSV文件时利用文件内统计信息进行剪枝的能力,指出其单文件部署与pandas等库零拷贝集成的易用性。

文章将DuckDB定位为与Polars同类的进程内库,用户通过pip或链接libduckdb直接加载,无需启动服务器即可在程序内执行分析查询。

DuckDB可通过replacement scan直接读取Python pandas DataFrame底层buffer,在类型布局匹配时实现零拷贝,避免先将数据物化到内部表,文章对比了传统ODBC/JDBC逐行序列化的高开销。

文章指出Arrow是DuckDB零拷贝场景的最优格式,其列式内存布局允许DuckDB直接读取或返回Arrow数据,绕过ODBC/JDBC的逐值函数调用与序列化,显著降低大型结果集的传输成本。

本文中 Apache Parquet 是 DuckDB 直接查询的主要文件格式之一,其列式存储与行组设计让 DuckDB 无需转换即可高效读取。每个行组包含每列的 min/max 统计信息,DuckDB 通过读取文件 footer 获取这些统计来跳过不满足谓词的行组,仅拉取所需列块字节。远程文件场景下,该机制避免下载整个文件,显著降低 I/O 开销,与 DuckDB 原生 zone map 作用类似。

本文指出 CSV 与 Parquet 相反,不是自描述格式,DuckDB 需先用 CSV sniffer 自动检测分隔符、引号、转义、类型及是否含表头。sniffer 默认采样 20480 行,依次完成方言检测、类型推断和表头判断,再生成可执行的读取计划。该过程让 DuckDB 能直接把普通 CSV 当作 SQL 表查询,但增加了启动开销。

本文中 Abstract Syntax Tree 是 SQL 解析阶段的产物,DuckDB 使用 Postgres 解析器 fork 将查询字符串转为包含 SELECT、Column、Literal 等节点的树结构。binder 随后在此树上完成名字绑定与类型检查,优化器则通过模式匹配子树进行 filter pushdown 等改写。没有 AST,后续的逻辑计划与物理计划转换无法进行。

本文把 ODBC 归为传统行式客户端协议,其逐行逐字段的 API 导致大量函数调用与内存拷贝,成为大型结果集返回时的主要瓶颈。DuckDB 通过 in-process 执行完全绕过该协议,避免了序列化/反序列化开销。文中引用 2017 年论文指出,此类协议常比查询计算本身更耗时。

本文将 JDBC 与 ODBC 并列,视为造成客户端序列化开销的典型 API,每次取值都需单独调用,百亿行结果会产生数亿次调用。DuckDB 因采用 in-process 模型,无需通过 JDBC/ODBC 传输数据,直接在同一进程内共享 Arrow 或 DataFrame 缓冲区。该设计让 DuckDB 在相同硬件上远快于通过 JDBC 访问的服务器数据库。

本文介绍 ADBC 作为 Arrow Database Connectivity 的缩写,它采用列式 Arrow 格式在系统间传输数据,避免 ODBC/JDBC 的逐行序列化。DuckDB 支持通过 ADBC 返回结果,进一步减少拷贝与类型转换。文中对比图显示,ADBC 在连接 Snowflake 等场景下显著优于传统驱动。

本文将 Vectorized Execution 列为 DuckDB 速度优势的核心设计之一。它通过以 2048 行 chunks 为单位处理数据,配合 pipeline 机制实现流式计算,避免逐行函数调用开销。该方式让执行阶段能高效利用 CPU 缓存和 SIMD 指令,支撑后续 morsel 级并行。

本文指出 Morsel-driven Parallelism 是 DuckDB 并行执行的关键机制。它不进行全局查询并行规划,而是让每个 pipeline 内部为不同线程分配独立 morsel 输入数据。线程各自维护本地状态,完成后并行合并,从而在 pipeline 层面实现多核高效扩展。

本文将 MVCC 作为 DuckDB 设计选择之一,采用乐观方式实现快照隔离。它支持分析查询与写入并发进行,避免传统锁竞争,同时保持查询结果的一致性。该机制与 in-process 执行结合,进一步降低事务开销。

本文详细说明 Zone Maps 存储在每个 row group 中,记录列的 min/max 值与 null 计数。扫描时先检查 zone map,谓词不满足的 row group 可被完全跳过,无需读取数据块。效果取决于列排序,时间戳或有序列能产生更窄范围,从而大幅减少 I/O。DuckDB 在查询 Parquet 时也复用文件自带的类似统计信息。

本文提到 DPhyp 是 DuckDB 连接顺序优化使用的动态规划算法之一。它将查询建模为图,逐步计算子集最优连接树,避免重复探索已求解的子问题,从而在多表连接场景下高效选出低成本执行顺序。

本文指出 DPccp 与 DPhyp 同为 DuckDB 连接顺序优化采用的动态规划方法。它基于连接图的连通子集递推最优解,在表数量较多时显著降低枚举开销,帮助优化器快速生成高质量物理计划。

该分类暂无内容
该分类暂无内容
该分类暂无内容

文章提及的公司之一,将DuckDB封装为云数据仓库产品,展示DuckDB从研究项目快速成长为商业分析引擎的实际落地案例。

本文发布方,使用DuckDB支撑数百万BI与分析查询,同时开发多引擎路由器以匹配不同查询的最优执行引擎,文章通过DuckDB internals分析体现其对查询引擎优化领域的专注。