返回正文目录

预聚合能力参考

本文说明 Foggy Java 引擎中的预聚合能力。该能力已有模型定义、匹配、SQL 改写和测试覆盖,但在具体项目中是否启用,应结合真实数据规模、刷新链路、查询口径和性能收益做项目级验证。预聚合是查询性能优化能力,不改变 TM/QM 的字段语义,也不是 MCP 工具协议的一部分。

1. 能力定位

preAggregations 用于在 TM 上声明已经存在或可被刷新任务生成的预计算聚合表。查询执行时,引擎会根据当前查询的维度、时间粒度、指标、过滤条件和运行时配置,判断是否可以把原始聚合查询改写到预聚合表上执行。

在完成项目级验证后,它适合以下场景:

它不适合替代完整的语义建模,也不应默认对所有查询开启。字段是否可查询仍由 QM 决定;预聚合只决定一次查询能否走更快的物理执行路径。

2. 使用状态口径

公开文档中应按以下口径理解预聚合:

层面 状态
引擎实现 Java 引擎包含预聚合定义加载、匹配、SQL 改写、rollup、hybrid 和 returnTotal 聚合路径
自动刷新 存在独立 add-on,可生成 DDL 和全量/增量刷新 SQL,并提供刷新服务入口
测试覆盖 已有匹配、集成、数据一致性、边界场景和刷新 SQL 生成相关测试
项目实践 需要在目标项目中结合真实业务模型、数据量、刷新策略和查询证据单独验证

因此,预聚合在当前文档中定位为“高级可选优化能力”,而不是默认查询路径或核心语义层契约。

3. 与 TM/QM/DSL 的关系

层级 作用
TM 声明物理表、字段、维度、指标,以及可选的 preAggregations 元数据
QM 决定哪些字段对查询调用方可见
JSON Query DSL 按 QM 暴露字段提交查询请求
预聚合匹配器 判断当前 DSL 查询生成的聚合计划是否可由某张预聚合表满足
SQL 改写器 在命中时把查询 SQL 改写到预聚合表

调用方不需要在 DSL 中显式指定预聚合表。是否命中预聚合由引擎根据模型定义和运行时配置决定。

4. 基本定义

preAggregations: [
    {
        name: 'dailyProductSales',
        caption: '每日商品销售预聚合',
        tableName: 'preagg_daily_product_sales',
        priority: 80,
        dimensions: ['salesDate', 'product'],
        granularity: {
            salesDate: 'day'
        },
        dimensionProperties: {
            product: ['caption', 'categoryName', 'brand']
        },
        measures: [
            { name: 'salesAmount', aggregation: 'sum', columnName: 'sales_amount' },
            { name: 'quantity', aggregation: 'sum', columnName: 'quantity' },
            { name: 'orderCount', aggregation: 'count', columnName: 'order_count' }
        ],
        refresh: {
            strategy: 'INCREMENTAL',
            watermarkColumn: 'salesDate$id',
            lookbackDays: 1
        },
        enabled: true
    }
]

4.1 顶层属性

属性 类型 必填 默认值 说明
name string 是 无 预聚合定义名称
caption string 否 无 显示名称
tableName string 是 无 预聚合物理表名
schema string 否 主表 schema 或数据源默认 schema 预聚合表 schema
priority number 否 50 匹配优先级,数值越高越优先
dimensions string[] 否 无 预聚合表覆盖的维度
granularity object 否 无 时间维度粒度映射
dimensionProperties object 否 无 预聚合表覆盖的维度属性
dimensionPropertyColumnNames object 否 无 维度属性到预聚合表物理列的映射
measures array 否 无 预聚合表覆盖的指标
filters array 否 无 预聚合表内置过滤条件元数据
refresh object 否 无 刷新策略元数据
enabled boolean 否 true 是否启用

4.2 指标属性

属性 类型 必填 说明
name string 是 对应 TM/QM 指标名
aggregation string 是 预聚合列所代表的聚合方式
columnName string 否 预聚合表中的物理列名

当前匹配逻辑主要覆盖 sum、count、min、max 等可安全 rollup 的聚合。avg 需要 sum + count 才能稳定上卷,当前不应作为预聚合 rollup 的默认假设。

4.3 刷新属性

属性 类型 必填 默认值 说明
strategy string 否 FULL 刷新策略,常见值为 FULL、INCREMENTAL
schedule string 否 无 调度表达式或宿主约定的调度标识
watermarkColumn string 否 无 增量刷新或 hybrid 查询使用的水位字段
lookbackDays number 否 无 增量刷新回看天数

刷新元数据本身不会让表自动存在。实际项目需要由工程侧创建预聚合表,并通过刷新任务、调度服务或外部数据作业维护其中的数据。

5. 匹配规则

预聚合命中需要同时满足以下条件:

条件 规则
查询类型 主要面向有维度和指标的聚合查询
维度 查询维度必须是预聚合维度的子集
维度属性 查询使用的维度属性必须被预聚合覆盖;id、caption 存在部分隐式映射规则
时间粒度 查询粒度不能比预聚合粒度更细,例如日预聚合可以上卷到月,月预聚合不能回答日查询
指标 查询指标必须被预聚合覆盖
聚合方式 查询聚合方式必须与预聚合列兼容
slice 条件 过滤字段需要能映射到预聚合表字段
自定义 SQL 包含自定义 SQL 条件的查询不会命中预聚合
启用状态 enabled: false 的预聚合不会参与匹配

当多张预聚合表都可满足查询时,引擎会结合 priority、维度覆盖差异和粒度差异选择更合适的表。

6. 执行模式

模式 说明
direct 查询粒度和字段集合可直接由预聚合表满足
rollup 预聚合表粒度更细,引擎在预聚合结果上继续聚合
hybrid 预聚合数据覆盖历史区间,源表补充水位线之后的新数据

hybrid 查询依赖水位字段和运行时配置,默认不应假定开启。开启后仍需要验证水位线、刷新周期和源表补偿区间是否符合业务口径。

7. 查询证据

命中预聚合后,执行上下文会记录预聚合使用情况。宿主系统可以在查询证据或调试信息中暴露这些字段:

字段 说明
preAggUsed 使用的预聚合名称
preAggMode 命中模式,如 direct、rollup、hybrid
preAggNeedsRollup 是否需要在预聚合表上继续上卷
preAggAggregateUsed returnTotal 聚合查询是否使用预聚合

这些字段用于解释查询计划和排查性能问题,不应被当作业务结果正确性的唯一证明。重要分析仍应结合源记录、SQL/DSL 证据和业务口径复核。

8. 刷新与维护

Foggy Java 项目中存在独立的预聚合 add-on,用于生成预聚合表 DDL、全量刷新 SQL、增量刷新 SQL,并提供刷新服务、调度和管理接口。该能力通常由宿主系统按部署环境接入。

项目中可以按两类方式维护预聚合表:

复杂维度属性、跨表属性、特殊方言 SQL 和事务边界需要在目标运行时验证。预聚合刷新链路属于工程集成能力,不应只依赖模型文件声明。

9. 当前边界

10. 建模建议