DuckDB 2.0 alpha 的触发器:按行比按语句贵三倍
来源:dev.to — 2026-10-15
📋 概述
DuckDB 2.0(代号 Cyanoptera)的预发布博文承诺支持「BEFORE/AFTER × 每行/每语句」的触发器,作者下载 alpha 版把八种组合对着 INSERT、UPDATE、DELETE 全试了一遍,结果五种还不能用,其中缺得最彻底的是 BEFORE——也就是大多数人最先想到、用来在数据落地前校验或拒绝一行的那一半。他用 50 万行的单次插入做基准:无触发器 0.073 秒;AFTER INSERT 每行触发器(记录 NEW.id)0.217 秒、约 3 倍;AFTER INSERT 每语句触发器(用过渡表记录整批)0.095 秒、约 1.3 倍。逻辑工作完全相同,差别只是按行的版本要穿过触发机器 50 万次,而不是作为一次集合操作完成。他还验证了过渡表确实每次语句只给一张、行数正确,所以语句级成本几乎与批量大小无关。同版本的「递归 CTE 引擎重写」他也复现了:换成 4 万节点的链式图后,1.5 版 18.57 秒、2.0 alpha 0.41 秒,约 45 倍。
🔑 核心要点
- 八种组合里五种还不能用,缺得最彻底的是 BEFORE,而预发布博文里当然没提。
- 基准:无触发器 0.073 秒,按行触发器 0.217 秒(约 3 倍),按语句加过渡表 0.095 秒(约 1.3 倍)。
- 他的建议很明确:审计日志或反规范化场景默认用 FOR EACH STATEMENT 加过渡表,因为今天在批量插入上便宜约两倍。
- 两个文档没写的限制:同一张表不能混用语句级与行级触发器,且 DROP TRIGGER trg_audit; 在这一版是语法错误,必须写 ON t。
- 递归 CTE 的声明经得起检验:4 万节点的链式图从 1.5 版的 18.57 秒降到 2.0 alpha 的 0.41 秒,约 45 倍。
💡 金句
按行的版本做的逻辑工作和按语句的完全一样,但它要穿过触发机器 50 万次,而不是作为一次集合操作完成。
👍 0
👎 0
← 返回 dev.to 首页