当前位置: 首页 > news >正文

DuckDB:从研究项目到广泛应用的数据库,为何如此之快?

引言

从2019年阿姆斯特丹CWI的一个研究项目起步,DuckDB发展成为过去十年中应用最广泛的数据库之一。它应用场景众多,包括笔记本、ETL管道、仪表盘、CI测试运行器、SaaS产品内的嵌入式分析,甚至能在iPhone上以100的规模因子运行TPC - H。许多公司围绕它开发出了实际产品,如MotherDuck将其封装成云数据仓库,Hex、Omni和Evidence等将其用作应用内执行引擎和缓存,Fivetran在数据湖写入器中使用它进行合并和压缩,Rill基于它构建开源BI工具,Greybeam也用它处理数百万次查询。

什么是DuckDB?

DuckDB是一个进程内分析型SQL数据库。“分析型”意味着它针对扫描数百万行数据进行过滤、聚合和连接的查询进行了优化,而非通过主键查找单条记录的查询;“进程内”表示它没有服务器,可像加载NumPy或Polars一样,作为库加载到程序中。它以单个小于20 MB的二进制文件形式发布,无需外部依赖,可通过`pip install duckdb`、`brew install duckdb`安装,或在C++项目中链接`libduckdb`。它能直接打开包含Parquet、CSV或JSON文件的目录,将其视为SQL数据库。而且,DuckDB还是目前最快的单节点分析引擎之一,常能与花费数百万美元的集群相抗衡。

查询在进程内运行

将DuckDB指向笔记本电脑上一个6 GB的Parquet文件,不到一秒就能得到结果,无需集群、设置、迁移和`CREATE TABLE`。大多数分析型数据库是服务器,如Snowflake、Postgres、BigQuery和Redshift,需打开连接,通过TCP发送SQL语句,等待结果返回,此过程中结果集记录要序列化、反序列化,对于大型结果集,这项工作耗时可能比查询本身还长。DuckDB是库,无守护进程、端口和集群,只需加载`libduckdb`到程序中调用函数即可。2017年,Mark Raasveldt和Hannes Mühleisen研究发现,客户端协议是查询过程中最慢的一步,主要受带宽限制和每个值处理开销影响。DuckDB与客户端处于同一进程,避开了这两个瓶颈。当Python脚本针对Pandas数据框执行查询时,DuckDB可使用替换扫描功能,理想情况下能直接读取Python进程的底层缓冲区,实现零复制。以Arrow格式返回结果或查询基于Arrow的数据,可避免传统API带来的逐行转换开销。

从SQL到逻辑计划

解析

SQL语句进入DuckDB后,第一步是解析为抽象语法树(AST),DuckDB使用Postgres解析器的一个分支。AST是查询的树形表示,解析过程将扁平字符串转换为引擎能理解的结构化对象。树形结构便于引擎其他部分工作,绑定器、优化器和物理规划器都依赖它处理查询。

绑定

绑定阶段根据目录解析AST中的每个名称,进行类型检查,输出绑定树,暴露未解析列、模糊引用和类型不匹配等错误,将原始SQL文本转换为类型化的树。

优化器

DuckDB的优化器由一系列小型、专注的转换组成,可单独检查和禁用。如过滤下推,将`WHERE`谓词靠近扫描操作;子查询展开,将相关子查询重写为连接操作;动态连接 - 过滤下推,在哈希连接中利用构建侧数据计算边界,推回到探测侧扫描操作;连接顺序优化,使用动态规划算法选择最优连接顺序。整个优化阶段通常在约一毫秒内完成,之后得到逻辑计划。

物理计划

将逻辑步骤映射到物理操作符

优化器输出的逻辑计划说明计算内容,但未指定算法。DuckDB遍历逻辑计划,根据节点输入形状和谓词选择物理操作符,输出物理计划,即由执行器知道如何运行的物理操作符组成的树。物理计划会拆分为多个管道。

管道

管道可想象成装配线,数据从一端进入,经过一系列站点处理后传递给下一个站点。如`WHERE`操作、投影操作、哈希连接的探测侧等可构成管道,管道能并行执行。

管道中断器

有些操作符需看到整个输入数据才能产生输出,如`ORDER BY`、`GROUP BY`、哈希连接的构建侧,这些操作符是管道中断器或接收器,标志着一个管道的结束和下一个管道的开始。物理计划由接收器连接起来的一系列管道组成。

接收器中的操作

接收器的操作分为接收、合并和最终处理三个阶段。接收阶段,每个线程接收数据块并写入本地状态;合并阶段,将各线程本地状态合并到全局状态;最终处理阶段,合并后的全局状态作为下一个管道的输入。

并行性是局部的

管道和接收器通过为线程分配数据块和本地状态实现并行运行,DuckDB一次只对一个管道进行并行处理,这是分块驱动的并行处理和向量化执行能有效工作的原因之一。

存储层

DuckDB数据库

DuckDB数据库是单一文件,通常扩展名为`.duckdb`或`.db`,数据分割成固定大小的块,文件头包含元数据,每个块带有校验和,用于检测数据是否损坏。

列、行组和区域映射

块内部各列分开存储,列存储在分析查询中更具优势。每列分割成行组,行组是并行处理的基本单位。每个行组带有区域映射,包含最小值、最大值和空值计数,可用于跳过不满足谓词的数据。区域映射的有效性取决于列的排序方式。

Parquet

用户常将DuckDB指向Parquet文件进行查询。Parquet是列存的,按列和行组存储最小/最大统计信息,DuckDB可利用这些信息确定满足查询谓词的行组,只读取所需列块。若文件在远程位置,DuckDB可按需获取字节,合理的`WHERE`子句可提高网络性能。

CSV

CSV文件无自我描述性,DuckDB通过CSV嗅探器确定列的分隔符、值是否加引号、引号如何转义、第一行是否包含列名以及每列的类型。嗅探器包括方言检测、列类型检测和标题行检测,基于采样数据工作,可调整采样大小。

执行

查询运行前需进行大量工作,包括解析、绑定、优化和编译成物理计划,存储层也会提前做很多工作。第2部分将从执行阶段开始介绍。

http://www.jsqmd.com/news/1048561/

相关文章:

  • 终极掌控:使用SMUDebugTool深度调优AMD Ryzen处理器的完整方案
  • 如何在OBS Studio中集成专业VST音频插件提升直播音质
  • 十二层PCB打样难?看看他三个月如何搞定交付
  • 水电工培训哪里强?1个月从零到师傅,高薪就业不迷茫! - 湖南阳光技术
  • AI工具会越来越多,真正的竞争力是那层让工具跑起来的底座
  • 下载AC FUN视频资源
  • 视觉驱动UI自动化:从DOM到像素的革命性跨越
  • 网盘直链下载助手:告别限速烦恼,九大网盘高速下载全攻略
  • 第16章 MemGPT / Letta —— Agent 记忆的「操作系统」
  • NeuroRebuild™实景动态重构引擎 技术白皮书
  • 2026扬州本地正规瓷砖空鼓维修服务商盘点|无损免拆砖修复,全域上门售后有保障 - 宅安选房屋修缮
  • 终极指南:5分钟掌握Cpp2IL逆向Unity IL2CPP的完整教程
  • 2026年6月最新劳力士中国官方售后客户地址热线电话服务网点 - 劳力士服务中心
  • 抖音无水印下载神器:3分钟学会批量保存高清视频的必备工具
  • 蓝牙电话方案-如何对接WebRTC的实时媒体流-技术预研
  • 2026高含金量国际EMBA测评与科学选型指南
  • 2026洛阳本地正规瓷砖空鼓维修服务商盘点|无损免拆砖修复,全域上门售后有保障 - 宅安选房屋修缮
  • 嵌入式GUI开发实战:emWin窗口管理器消息机制、ToolTips与多图层应用详解
  • Windows 11任务栏拖放功能修复:高效恢复系统原生操作体验
  • CTF逆向实战:位操作加密(左移4右移4)原理与破解
  • 2026上海PLC培训机构名录:核心实力客观对比 - 互联网科技品牌测评
  • 2026年6月最新浪琴中国官方售后服务地址热线及客服网点电话 - 浪琴服务中心
  • 简单理解:为什么SVPWM没看到提反Clarke变换
  • Agent 核心原理:从概念到可交付结果
  • public-apis 项目深度解析:442K Stars的免费API大全
  • Gemini 3.5国内一键可用:服务发现层软适配实战指南
  • llama.cpp中MoE模型卸载优化实战指南
  • 在哪个软件找工作真实可靠?五大招聘平台实测对比 - 博客万
  • 鸿蒙物理 108 篇 第十八篇 开合吞吐场域交互法则
  • emWin仿真API实战:嵌入式GUI硬件模拟与按键集成开发指南