告别全量扫描:一个技能包让 AI 掌握增量计算
2026/6/16 20:02:14 网站建设 项目流程

每次刷新都是一次"全量重算"

你的数据管道里,有多少张表是这样工作的:

每隔一小时,把源表全量扫一遍,重新算一次聚合,覆盖写入目标表。

数据量 1TB,每次刷新就扫 1TB。数据增量只有 0.1%,计算成本却是 100%。

这不是个别现象,而是批处理 ETL 的常态。更麻烦的是,当你想把刷新频率从"每小时"压缩到"每分钟",全量重算的代价会让整个链路直接撑不住。

两条路,都不好走

面对这个问题,通常有两条路:

路径一:引入流计算引擎。Flink 确实能做到秒级实时,但代价是重构整条链路——EventTime、Watermark、Window、状态后端,每一个概念都需要重新学习,现有的 SQL 资产几乎无法复用。

路径二:继续忍受批处理的延迟。业务数据"昨天的",报表永远慢半拍。

但其实还有第三条路:增量计算——只处理变化的数据,用批处理的 SQL 语义,实现接近流计算的刷新频率。

问题在于,增量计算的正确实现并不简单。AI 编程助手"知道"增量计算的公式,但在实际生成代码时,往往会在关键细节上出错。

这些都正是Incremental Skills要解决的问题:我们发现,增量计算的核心原理是通用的,然而,这些知识长期分散在学术论文、系统文档和工程师经验中,缺乏系统性的整理。与此同时,AI 编程助手正在改变软件开发范式,但对增量计算的理解往往停留在理论层面,在实际生成代码时容易遗漏关键细节。我们希望借助这套完整的增量计算技能包,系统性地呈现增量计算的知识体系,让开发者都可以在不迁移数仓的前提下,以尽可能少的改动体验到增量计算的收益。

核心模型:Snapshot 与 Delta

增量计算的基础是两个原语:

  • Snapshot(V):版本 V 时刻的全量快照
  • Delta(V1, V2):两个版本之间的行级变化,每行携带 __weight 列(+1 表示插入,-1 表示删除,UPDATE = 旧行 -1 + 新行 +1)

__weight 是增量计算的核心。以聚合为例:

-- 全量聚合(扫全表) SELECT group_key, SUM(value) FROM snapshot GROUP BY group_key -- 增量聚合(依赖上次的聚合结果,处理增量数据) SELECT group_key, SUM(sum_res) FROM ( -- 旧状态:每个group key只保留1行 SELECT group_key, sum_res FROM state UNION ALL -- 新插入的增量数据 SELECT group_key, value * __weight FROM insert_delta ) GROUP BY group_key;

删除的行 __weight = -1,乘以 value 后贡献负值,自动从累计结果中扣除。这一行代码的差异,决定了增量计算是否正确。

场景一:电商大促实时销售看板

业务需求:大促期间,运营需要每分钟看到各品类的实时销售额和订单量,用于动态调整活动策略。

原始 SQL:

SELECT c.category_name, COUNT(o.order_id) AS order_count, SUM(o.amount) AS total_amount FROM orders o JOIN categories c ON o.category_id = c.id WHERE o.status = 'paid' GROUP BY c.category_name

这条 SQL 包含 JOIN + GROUP BY,增量维护需要分两层处理:

Layer 1(JOIN 层):对 orders 和 categories 的 Delta 分别应用 JOIN 的增量规则。例如,当orders产生新数据的时候,只需要将这部分新数据与categories进行JOIN即可得到当前层的增量结果,而无需读取orders的历史数据。

Layer 2(聚合层):对JOIN产生的 Delta 应用 Aggregation 的增量规则。COUNT 和 SUM 都是可撤回的——删除的行通过 __weight = -1 自动从累计值中扣除,无需重扫历史数据。

每次刷新,只处理新增/变更的订单行,计算量与订单增量成正比。大促高峰期每分钟新增 10 万笔订单,只需结合历史聚合结果,处理这 10 万行,而非全量的数亿行历史订单。

场景二:商品最低价格订阅

业务需求:价格监控系统需要实时维护每个商品的历史最低价,当最低价发生变化时触发用户订阅通知。

原始 SQL:

SELECT product_id, MIN(price) AS min_price FROM price_history GROUP BY product_id;

MIN 是不可撤回聚合—— 例如当一条价格记录被删除时,如果它恰好是当前最低价,你无法通过简单的加减法得到新的最低价,必须重新扫描该商品的所有历史价格。

增量技能包对此的处理策略是:受影响分组重算。

每次刷新时,先从 Delta 中找出哪些 product_id 发生了变化,然后只对这些商品重新执行 MIN(price) 查询。如果一次刷新涉及 500 个商品的价格变动,只需重算这 500 个商品,而非全量的百万级商品。

这与可撤回聚合的处理方式截然不同,也是 AI 在没有领域知识支撑时最容易混淆的地方。

AI + 技能包:正确实现的关键

现有的AI Agent在增量计算上的失误,往往不是"不知道",而是"知道但遗漏了细节"。技能包系统性地覆盖了这些细节,在此示例一些AI常犯的错误:

Delta 去重:同一行在一个批次内可能出现多次(多次更新产生一系列先删后插的数据记录)。直接应用未去重的 Delta 会导致 PK 冲突或幽灵行。正确做法:GROUP BY 所有列 HAVING SUM(__weight) != 0。

数据清理:当Aggregate一个分组的所有行都被删除后,状态表中该分组的 accumulated_count 会归零。如果不清理,这个"空分组"会作为幽灵行出现在查询结果中。

多层版本传播:大部分计算都需要依赖自身的历史状态和输入源的增量数据,Layer N+1 的 from_version 必须来自自己的 Profile,而不是 Layer N 的 Profile。混淆这一点会导致数据重复处理或丢失。

空集 NULL 保护:SUM() 在无匹配行时返回 NULL,后续 NULL + 5 = NULL。必须用 COALESCE(SUM(...), 0) 保护。

诸如此类的陷阱,每一个都能让看似正确的增量 SQL 在生产环境中悄悄产生错误数据。

安装与使用

Incremental Skills 遵循 Agent Skills 规范:

https://agentskills.io/home

支持 Claude Code、Cursor、Kiro、Copilot CLI、Gemini CLI、Codex 等主流 AI 编程助手。

安装方式,执行:

npx skills add clickzetta/incremental-skills

安装后,直接在AI Agent中使用:

/incremental-computation 将批处理任务 order_summary 转换为增量计算 /incremental-computation REFRESH TABLE order_summary

AI Agent 会加载技能包,确认如何获取 Snapshot、Delta、Schema 和版本信息,然后按照算法参考生成正确的增量 SQL。

相关的内容一并开源整理在了GitHub中 Incremental-Skills,包含完整示例,感兴趣的朋友欢迎移步查阅。
https://github.com/clickzetta/incremental-skills

结语

Incremental Skills 由云器科技开源(Apache 2.0)。云器在自研的 ClickZetta Lakehouse 中深度实践增量计算多年,并发布了《增量计算技术白皮书》。技能包将这些实践经验系统化,以引擎无关的形式开放给社区。

如果你的数据管道正在被全量重算拖累,或者你想让 AI Agent真正理解增量计算而不只是"知道公式",不妨试试这个技能包。

如果你的场景需要应用于严肃的生产环境,并且对数据安全性和时效性有明确要求,建议直接使用 ClickZetta Lakehouse——增量计算在其中是引擎原生支持的能力,而非依赖 AI 生成的 SQL 拼接。配合 cz-cli 可以在命令行直接管理动态表的增量刷新,开箱即用。

项目安装地址:npx skills add clickzetta/incremental-skills

获取cz-cli安装文档请访问:

https://www.yunqi.tech/documents/setup_cz_cli


云器科技官网 - 改变数据的使用方式
更多内容,欢迎关注「云器科技」官网!
云器科技-多云及一体化数据平台提供

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询