Skip to content

一次查询在 Cube 中是如何执行的

理解 Cube 的最好方式之一,就是追踪一条查询的完整生命周期。

1. 查询的起点:不是表,而是语义成员

在 Cube 中,消费端通常不是直接说:

sql
SELECT SUM(amount) FROM orders ...

而是表达成更语义化的请求,例如 REST API:

json
{
  "measures": ["orders.total_amount"],
  "dimensions": ["orders.status"],
  "timeDimensions": [
    {
      "dimension": "orders.created_at",
      "granularity": "month"
    }
  ]
}

这里的关键点是:

  • 请求里出现的是 orders.total_amount 这类语义成员;
  • 不需要消费端自己写底层聚合 SQL;
  • 也不需要消费端自己决定 join 与缓存策略。

2. 第一步:API Instance 接收请求

无论你用的是 REST、GraphQL 还是 SQL API,入口都可以理解为 Cube 的 API 层。

官方部署文档指出:

  • API Instances 处理传入 API 请求;
  • 它们要么查询 Cube Store 的预聚合数据;
  • 要么查询连接的数据源中的原始数据。

3. 第二步:解析语义查询

API 层接到请求后,会解析以下信息:

  • 需要哪些 measures;
  • 需要哪些 dimensions;
  • 时间维度是什么;
  • 过滤条件是什么;
  • 排序、分页、limit 是什么;
  • 当前请求的安全上下文是什么。

如果是 SQL API,还会先把 SQL 中引用的 cube / view 成员映射回语义层对象。

4. 第三步:定位 cube / view 与 join path

Cube 接下来会根据语义模型:

  • 找到对应 cube 或 view;
  • 决定查询涉及哪些底层对象;
  • 解析可用 join path;
  • 套用 view 中定义的暴露范围与治理规则。

这一步对于“避免 AI 瞎猜 join”特别关键。

5. 第四步:应用权限与安全规则

Cube 会结合:

  • access policies;
  • member-level security;
  • security context / user attributes;
  • API scopes;

决定:

  • 哪些成员可见;
  • 哪些行可见;
  • 哪些 API 可访问。

所以 Cube 的权限并不是查询结束后再过滤,而是直接参与查询生成过程。

6. 第五步:判断缓存与预聚合是否命中

这是性能层的关键步骤。

第一层:结果缓存

Cube 会先看是否能命中 in-memory cache。

第二层:pre-aggregations

如果查询可以由某个预聚合回答,Cube 会优先用预聚合。

官方文档描述这一过程时强调:

  • Cube 会分析查询;
  • 在已定义的 pre-aggregation 规则中选择最优一个;
  • 如果有合适且最新的预聚合,就用它而不是访问原始数据。

7. 第六步:走两条不同路径之一

路径 A:命中 Cube Store / 预聚合

text
语义查询
→ 匹配到可用 pre-aggregation
→ 查询 Cube Store
→ 返回结果

这通常意味着:

  • 延迟更低;
  • 并发更高;
  • 对上游数仓压力更小。

路径 B:未命中预聚合,回源查询

text
语义查询
→ 生成底层 SQL
→ 查询原始数据源
→ 聚合结果
→ 返回结果

这条路径依然是合法的,只是性能可能不如命中预聚合时稳定。

8. 第七步:返回结构化结果

Cube 最终返回的不是“数据库原始表”,而是一个已经按语义成员组织好的结果集。

对上层消费者来说,结果具有几个好处:

  • 字段名称稳定;
  • 与建模定义一致;
  • 不需要每个客户端自己理解底层表结构。

9. Refresh Worker 在哪一步起作用

Refresh Worker 不在用户请求的临界路径上直接处理前台查询,但它对查询性能影响极大。

根据官方部署文档,它会:

  • 更新 pre-aggregations;
  • 保持 refresh keys 最新;
  • 在后台失效 in-memory cache。

因此它的作用像是:

提前把“将来会被查到的聚合结果”准备好。

10. 为什么这个执行流程对 AI 很友好

AI Agent 的查询行为通常不是一次性的,而是连续探索式的:

  • 先看总量;
  • 再按地区拆分;
  • 再按产品拆分;
  • 再追问异常月份;
  • 再拉一个最近 12 个月趋势。

在这种模式下,如果没有语义层:

  • 每一步都需要重新猜字段;
  • 每一步都可能重新生成错误 SQL;
  • 每一步都可能造成数仓高成本扫描。

而有了 Cube:

  • 语义成员可复用;
  • join 路径被固定;
  • 权限规则可统一;
  • 高概率命中缓存或预聚合。

11. 中文教程里建议怎么画这条链路

最适合的叙述方式是:

text
查询请求
→ 语义解析
→ 安全校验
→ 预聚合匹配
→ 回源或查 Cube Store
→ 返回结构化结果
→ 后台 Worker 持续保鲜

这比单纯说“Cube 会生成 SQL”更完整。

一句话总结

Cube 查询执行的本质,是把“语义请求”翻译为“受治理、可优化、可缓存”的底层执行计划;前台由 API Instances 处理,后台由 Refresh Worker 维护,性能由 Cube Store 与预聚合保障。

本站基于官方文档与官方代码仓库整理,为第三方非官方中文教程,与 Cube Dev, Inc. 无隶属、授权或背书关系;Cube、Cube Core 及相关标识归其各自权利人所有。