1. 从Cube到Query的演进背景
在传统SAP BW(Business Warehouse)体系中,Cube(多维数据集)长期作为分析模型的核心载体。这种架构下,数据工程师需要先构建物理Cube,再基于Cube创建Query(查询)供最终用户使用。整个过程涉及多层数据冗余存储,ETL流程复杂,维护成本居高不下。
2015年前后,随着SAP HANA内存计算平台的成熟,SAP推出了新一代的CDS(Core Data Services)建模框架。其中Analytical Projection Views作为专门为分析场景设计的CDS视图类型,实现了从物理Cube到逻辑Query的直接映射。这种变革的本质是将OLAP(联机分析处理)能力下沉到数据库层,利用HANA的列式存储和并行计算特性,在运行时动态生成分析结果。
技术提示:与传统Cube相比,CDS Analytical Projection Views不再需要预计算和存储聚合数据。其执行计划由HANA优化器在查询时动态生成,这使得模型调整后的结果可以立即反映,不再需要耗时的手动处理。
2. Analytical Projection Views的核心架构
2.1 基础语法结构
一个典型的Analytical Projection View定义如下:
abap复制@Analytics.dataCategory: #PROJECTION
define view Z_SALES_ANALYSIS
as projection on Z_SALES_CUBE
{
key customer,
product,
@DefaultAggregation: #SUM
amount,
@Analytics.derivation: {
semantics: #AMOUNT.CURRENCY
with: currency }
currency
}
关键注解解析:
@Analytics.dataCategory: #PROJECTION声明这是一个分析投影视图@DefaultAggregation定义度量字段的默认聚合行为@Analytics.derivation实现语义属性的关联(如金额与货币的绑定)
2.2 与底层Cube的映射关系
Analytical Projection View必须基于一个Analytical Cube View构建。这种依赖关系体现在:
- 投影视图的字段必须是源Cube视图字段的子集
- 维度字段必须保持相同的key属性
- 度量字段的聚合行为可以重新定义但数据类型必须兼容
技术细节:在运行时,HANA会先将Projection View的请求转换为对底层Cube的查询,再利用Cube的星型模式优化查询性能。这种设计既保留了Cube的性能优势,又提供了Query层的灵活性。
3. 实战:构建企业销售分析模型
3.1 创建基础Cube视图
首先需要定义作为数据源的Cube视图:
abap复制@Analytics.dataCategory: #CUBE
define view Z_SALES_CUBE
as select from snwd_so_inv_item
association [0..1] to snwd_bpa as _customer on $projection.customer = _customer.bp_id
association [0..1] to snwd_pd as _product on $projection.product = _product.product_id
{
key _customer.bp_id as customer,
key _product.product_id as product,
key snwd_so_inv_item.currency_code as currency,
@DefaultAggregation: #SUM
snwd_so_inv_item.gross_amount as amount,
// 暴露关联用于导航
_customer,
_product
}
3.2 设计Projection视图
基于上述Cube创建面向业务用户的投影视图:
abap复制@Analytics.dataCategory: #PROJECTION
@AccessControl.authorizationCheck: #CHECK
define view Z_SALES_ANALYSIS
as projection on Z_SALES_CUBE
{
// 维度字段
key customer,
product,
// 度量字段
@DefaultAggregation: #SUM
@Semantics.amount.currencyCode: 'currency'
amount,
// 货币字段
@Semantics.currencyCode: true
currency,
// 导航属性
_customer.name as customer_name,
_product.category as product_category
}
3.3 添加计算指标
通过注解实现动态计算字段:
abap复制@Analytics.dataCategory: #PROJECTION
define view Z_SALES_ANALYSIS
as projection on Z_SALES_CUBE
{
// ...基础字段同上...
// 计算字段:单价
@Analytics.derivation: {
formula: "DIVISION(amount, quantity)",
variables: [{
name: 'quantity',
mapping: snwd_so_inv_item.quantity }]
}
unit_price,
// 条件计算:大客户标记
@Analytics.derivation: {
case: {
when: "amount > 100000",
then: "'A'",
else: "'B'"
}
}
customer_segment
}
4. 性能优化实战技巧
4.1 分区策略优化
对于海量数据场景,建议在底层Cube实施分区:
abap复制@Analytics.partition: {
algorithm: #RANGE,
column: 'fiscal_year',
ranges: [
{ from: '2021', to: '2021' },
{ from: '2022', to: '2022' }
]
}
define view Z_SALES_CUBE
as select from snwd_so_inv_item
// ...
4.2 聚合感知配置
通过@Aggregation.default和@Aggregation.usage注解指导查询优化:
abap复制@Analytics.dataCategory: #PROJECTION
define view Z_SALES_ANALYSIS
as projection on Z_SALES_CUBE
{
@Aggregation.default: #SUM
@Aggregation.usage: #DIMENSION
key customer,
@Aggregation.default: #MAX
@Aggregation.usage: #NONE
last_order_date
}
4.3 常见性能陷阱
- 过度投影:避免在Projection视图中包含不需要的字段,特别是大文本字段
- 嵌套过深:Projection视图链不宜超过3层(Cube → Projection → Projection2)
- 动态计算滥用:复杂公式计算应考虑下推到Cube层或通过HANA计算视图实现
5. 与ABAP报表的集成方案
5.1 ALV集成示例
在ABAP程序中直接消费Projection视图:
abap复制DATA: lt_sales TYPE TABLE OF z_sales_analysis.
SELECT * FROM z_sales_analysis
INTO TABLE @lt_sales
WHERE customer_segment = 'A'.
cl_salv_table=>factory(
IMPORTING
r_salv_table = DATA(lo_alv),
CHANGING
t_table = lt_sales
).
lo_alv->display().
5.2 OData服务发布
通过注解快速生成OData服务:
abap复制@OData.publish: true
@AccessControl.authorizationCheck: #CHECK
define view Z_SALES_ANALYSIS
as projection on Z_SALES_CUBE
{
// ...
}
生成的服务支持标准的$filter、$orderby等OData查询选项。
5.3 权限控制实现
结合CDS角色注解实现行级权限:
abap复制@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Sales Analysis'
define view Z_SALES_ANALYSIS
as projection on Z_SALES_CUBE
with PRIVILEGED ACCESS
{
// ...
@AccessControl.role: 'SALES_REGION'
region,
@AccessControl.role: 'SALES_ORG'
sales_org
}
6. 调试与问题排查
6.1 SQL跟踪技巧
使用以下方法查看生成的SQL:
abap复制CL_ABAP_SESSION=>SET_TRACE_ON( ).
SELECT * FROM z_sales_analysis INTO TABLE @DATA(lt_data).
CL_ABAP_SESSION=>SET_TRACE_OFF( ).
然后在ST01跟踪中查看实际执行的SQL语句。
6.2 常见错误处理
- 字段类型不匹配:检查Projection视图与Cube视图的字段类型映射
- 聚合行为冲突:确保度量字段的@DefaultAggregation注解一致
- 权限不足:检查WITH PRIVILEGED ACCESS的使用是否必要
6.3 性能分析工具
使用HANA Studio的Plan Visualizer分析查询执行计划,重点关注:
- 是否有效利用了列存储
- 分区裁剪是否生效
- 临时结果集的大小
我在实际项目中发现,90%的性能问题可以通过优化底层Cube的分区策略和索引设计来解决。特别是在处理千万级以上的销售数据时,合理的范围分区(按年度/季度)可以带来数量级的性能提升。
