原文地址:https://motherduck.com/blog/DuckDB-1.5-features-I-am-excited-about
我对 DuckDB 1.5 功能感到兴奋
2026/03/09 - 10分钟阅读
作者:Alex Monahan
鸭子在糖果店里的图片
DuckDB Labs 的团队和 DuckDB 社区发布了 DuckDB 1.5!它充满了各种各样的好东西------每次新版本发布都让我感觉自己像个在糖果店里的孩子。请务必查看 DuckDB 博客上的《DuckDB 1.5.0 发布公告》!在 MotherDuck,我们对 1.5 版本感到非常兴奋,并将在未来几周内发布对 DuckDB 1.5 的支持。感谢 DuckDB Labs 的各位以及所有贡献者!
DuckDB 团队的发布文章介绍了很多 1.5 版本的重大新功能(说真的,去读读那篇文章!),但我想分享一下为什么我对这些功能如此兴奋,以及为什么你也应该如此。毕竟,让别人来夸赞你的代码总是更有趣!以下是一些我认为值得特别提及的新功能。
使用 VARIANT 类型加速 JSON 查询
鸭子用吉他 shredding JSON 的图片
现在鸭子们可以在吉他上 shredding JSON 了!
使用 VARIANT,您可以自动存储每行具有不同数据类型的值,同时在查询这些数据时仍能获得卓越的性能。这在处理具有不同结构的 JSON 数据时最为实用。在很多情况下,数据大体形状相同,但又不完全一致(这被创造性地称为半结构化数据......)。这可能来自可观测性数据(每个服务记录在其特定领域重要的键值)、可能随时间变化的 API 输出,或者只是普通的杂乱数据。
在 AI 时代,我怀疑数据会变得更加结构化......我相信这将在很多地方都非常有用!
那么,这就是 VARIANT 的用途,但为什么要用它呢?用一个词概括:速度。用多个词概括:10 到 100 倍的速度提升。DuckDB 现有的半结构化数据功能------JSON 类型------将数据存储为文本以保持灵活性。然而,VARIANT 类型会自动将 JSON 数据"分解"到不同的列中(并且由于是自动的,它保留了灵活性!)。因此,如果您只需要 JSON 数据中的几个部分,您只需从磁盘上获取这些部分即可。此外,它们已经处于完美的数据类型中,而不是总是 VARCHAR。在内部基准测试中,我们在这类查询中看到了超过 100 倍的性能提升。
即使在快速改进的 DuckDB 中,也不是每个版本都能获得 100 倍的性能提升,更不用说针对如此普遍的工作负载了。意义重大。
使用 VARIANT 的感觉很像使用 JSON。如果您创建一个 VARIANT 列,您可以像这样查询单个键:
sql
CREATE TEMP TABLE go_ducks AS
SELECT {duck: 42, goose: -1}::VARIANT as my_variant;
SELECT my_variant.duck
FROM go_ducks;
加速真实世界查询
SQL 的现实世界是混乱的。如果您在这个领域待过一段时间,您会像我一样见过 3000 行的庞然大物。您甚至可能写过其中一些,我也有罪!需要优化的往往不是那些简短的查询。基准测试是有用的,但它们无法涵盖所有情况,因此现实世界的性能通常取决于数据库为我们做了多少优化工作。
您真实的数据库性能在很大程度上取决于数据库的友好程度和帮助程度。在 Agent 时代更是如此!SQL 代码在 2026 年只会变得更加复杂......
DuckDB 1.5 在这方面有大量影响深远的功能。
基础 Min / Max 查询速度提升 6 到 18 倍
在很多情况下,我需要知道整个表的最小值或最大值:我需要最新的时间戳来判断我的缓存是否是最新的,或者我想要最大的 customer_id 以便生成一个新的。当我在探索新数据时,我想知道数据集的历史有多久,只需一个快速的查询:
sql
SELECT min(event_date)
FROM shipments
在 DuckDB 1.5 中,这可以快 6 到 18 倍!
怎么做到的?DuckDB 的存储格式会自动将数据分成行组,默认为 122880 行。对于每个行组,它会存储该行组中每一列的统计信息,包括存在的最小值和最大值。通过这个新功能,DuckDB 不再需要检查每一行来知道表的最小值或最大值------它只需要检查统计信息!正如您所料,检查 1 个值比检查 122880 个值要快得多!
而且这个功能不仅限于 DuckDB 文件,它也适用于 Parquet 文件!Parquet 使用相同类型的行组概念,因此它也有类似的统计信息。任何足够简单的查询都会自动获得这种加速,适用于两种文件类型------无需任何更改!
更复杂的连接可以快得多
如果每个数据库模式都是美丽而原始的星型结构就好了......但在现实世界的分析中,连接可能变得复杂。DuckDB 一直能够处理这些类型的连接,但在过去,它有时会回退到"最小公分母"连接算法:可靠的块嵌套循环连接。这听起来可能非常深入数据库领域,但实际上这意味着 DuckDB 中复杂的连接通常比基本连接慢得多。
DuckDB 1.5 现在可以检测到更多情况,从而使用其极快、业界领先的哈希连接算法。在实践中,这很容易带来超过 10 倍的性能提升。如果至少有一个等值条件,即使带有复杂表达式的连接也可以执行快速的哈希连接,然后将复杂表达式作为残留谓词(连接之后发生的过滤步骤)应用。混乱的连接也能获得更快的速度!这是另一个你在基准测试中看不到,但在日常工作中能切实感受到的好处。
Top N 分组查询速度提升高达 40 倍
在许多情况下,检索组内的 Top N 项非常重要。这听起来有点抽象,但它包括如下查询:每个类别的前 10 种产品,每个供应商的最后 5 批发货,或者每个微服务最近的 100 条日志。然而,最常见的用例是智能地去重。例如,显示每个客户的最新值。
计算这个有两种标准方法:使用 row_number() 过滤器,或者使用 max_by 聚合函数(也称为 arg_max)。您可能之前见过这样的去重查询:
sql
WITH row_number_added AS (
SELECT
*,
row_number() OVER (
PARTITION BY group_col
ORDER BY update_date DESC
) AS rn
FROM tbl
)
SELECT *
FROM row_number_added
WHERE rn = 1
现在,无论您使用哪种语法,DuckDB 都会自动选择最优算法。不仅如此,通过省去中间计算,它的速度远远超过了这两种方法的手动实现。在某些情况下,它可以快多达 70 倍!不是快 70%,而是 70 倍。
这对我来说是个人体验!我曾指导过至少 10 个不同的客户如何手动调整他们的查询,以使用 arg_max / max_by 方法而不是 row_number()。我甚至为此写了一篇博文,并附带了微基准测试。我居然被取代了!!不过,我非常乐意把这个任务交给机器......感谢让这一切成为可能的人们!
不要重复自己,对于数据库来说也是如此......
复杂的 SQL 查询经常以不同的方式重用相同的数据片段,通常是通过 CTE(公用表表达式),它使用 WITH 子句。DuckDB 1.5 现在在检测可重用的分析片段方面更加富有创造性。这个技术的术语是"公共子计划消除",即在多个地方重用的计算被计算一次并物化(存储在内存/本地磁盘中),以便在同一查询的后续部分中重用。这意味着 DuckDB 需要做的工作更少,您最复杂的查询可以运行得更快!即使 CTE 彼此相似,也支持模糊匹配,它们的分析超集可以被计算一次并在两个地方重用。
符合此模式的 TPC-DS 和 TPC-H 查询可以快多达 80%!
读取整个文件夹的 DuckDB 文件
在 DuckDB 中使用 Parquet 文件的一个优点是,您可以像在 SQL 语句中查询单个表一样,查询它们的整个文件夹结构。现在,DuckDB 文件也具有同样的能力!您可以使用以下命令读取整个文件夹:
sql
SELECT * FROM read_duckdb('*.duckdb')
这样做的主要好处是,DuckDB 作为 AWS S3 等云对象存储上的文件格式使用起来更加方便。您现在可以选择将数据存档构建为许多单独的 DuckDB 文件,与 Parquet 相比,这可能在读取性能和压缩方面都有优势。
写入 Azure Blob 和 ADLSv2 存储
DuckDB 的 COPY 语句现在可以直接写入 Azure Blob 存储和 ADLSv2 存储。这真正释放了 Azure 作为您可以使用 DuckDB 管理文件(而不仅仅是查询它们)的地方的潜力。Azure 是最后一个支持写入的主流云对象存储,所以现在 DuckDB 是一项完全多云的技术!这是一个相当了不起的里程碑。
DuckLake 0.4 发布,包含宏、排序和修复
DuckLake 正在彻底改变作为表湖仓格式的含义。它使用起来非常简单,并且具有显著更快的读取查询性能------比其他格式延迟最多低 10 倍!它通过一种既传统又激进的方法实现了这一切:使用 SQL 数据库作为湖仓目录和所有湖仓元数据,而不是在对象存储上使用数千个元数据文件。您的完整数据集仍然存在于对象存储上的 Parquet 文件中(与 Iceberg 格式相同!),但查询通常通过使用数据库来获取元数据,从而节省了数秒的时间。
DuckLake 0.4 拥有各种很棒的新功能,如宏、排序/聚簇表和删除内联。我们将在未来的文章中深入介绍它们。
DuckLake 1.0 将于 4 月发布,所以请务必继续关注!
Iceberg 和 Delta Lake
Iceberg 和 Delta Lake 在 DuckDB 中都继续受到高度关注。对于 Delta Lake,通过 Unity Catalog 的写入支持得到了改进。DuckDB 的 Iceberg 扩展在使用 AWS Glue 目录时,也可以通过 CREATE TABLE 语句中的表属性来写入表。Iceberg 在 1.5.1 版本中还有更多功能!
非阻塞检查点
我把这一节留到最后,因为它非常重要。这项工作标志着 DuckDB 在处理并发方面的又一次飞跃。DuckDB 可能始于对卓越单机分析的愿景,但它已经发展成为在各种用例中都不可或缺的工具,包括具有高读写并发的场景。现在,无论何时对 DuckDB 文件进行检查点操作,您都可以同时进行读取、写入和删除操作。这消除了性能的许多可变性,并将已经高度优化的 TPC-H 工作负载的吞吐量提高了 17%!这需要一些非凡的工程努力!DuckDB 现在有多个不同的预写日志文件!这样,您可以将一个 WAL 文件的内容推送到 DuckDB 文件中,同时使用另一个 WAL 文件完全并行地修改数据库。
快来了解更多!
无论您如何使用 DuckDB,1.5 版本都为您带来了一些实实在在的好处!试试看吧,MotherDuck 将在几周内全面升级到 DuckDB 1.5。