DAX 底层计算过程演示——ADDCOLUMNS + 复杂上下文环境

关于 DAX 理论的资料很多,DAX 理论帮助我们理解和预测 DAX 的计算结果,但 DAX 在底层实际是怎么计算的却少有人谈及。本篇以一段在复杂上下文环境中通过 ADDCOLUMNS 进行计算的 DAX 查询代码为观察对象,使用 DAX Stuido 查看查询计划,展示其在存储引擎中执行了哪些数据查询,揭示公式引擎如何组装这些数据最终得出计算结果。

数据环境

数据文件 下载

1、DFact——数据表,由 Date 和 Amount 两列组成

image

2、Dates——日期表,由 DAX 代码生成

image

3、两张表通过 [Date] 列建立关系,Dates[Date](1) — (*) DFact[Date]

image

4、度量值

SumAmount = SUM('DFact'[Amount])
SumxBug = SUMX(VALUES(Dates[Year]),[SumAmount])

DAX 查询代码

EVALUATE
CALCULATETABLE (
    ADDCOLUMNS ( VALUES ( Dates[Year] ), "SumxBug", [SumxBug] ),
    TREATAS (
        {
   
    ( 2019, 1 ), ( 2019, 2 ), ( 2020, 11 ), ( 2020, 12 ) },
        'Dates'[Year],
        'Dates'[Month Num]
    )
)

CALCULATETABLE​ 以 TREATAS​ 作为调节器,为ADDCOLUMNS​ 提供筛选上下文,ADDCOLUMNS​ 在该上下文中扫描 Dates[Year]​并计算度量值[SumxBug]

运行结果如下:

image

DAX 理论

先用 DAX 理论分析一下计算结果。

下面的图中使用红色数字标记了某些列,这是故意的,后面有用处。

1、CALCULATETABLE​ 以 TREATAS​ 作为调节器,为 ADDCOLUMNS​提供外部筛选器。

image

2、在外部筛选上下文中计算 ADDCOLUMNS​ 一参 VALUES(Dates[Year])

image

3、ADDCOLUMNS​以 2# 数据集为迭代对象,逐行读取行上下文,在外部筛选上下文和行上下文中计算[SumxBug]
SumxBug = SUMX(VALUES(Dates[Year]),[SumAmount])

[SumxBug] 将行上下文转换为筛选上下文,并覆盖外部筛选上下文。

image

4、计算 SUMX(VALUES(Dates[Year]),[SumAmount])

迭代 Dates[Year]​ 并计算 [SumAmount]​ ,这里出现第二层行上下文​
在这里插入图片描述

5、合并成最终的结果

完整的分析流程如下
在这里插入图片描述
注意在这个过程中存在多层行上下文的事实。

DAX 底层计算过程

以下内容将涉及 DAX 引擎和查询计划,相关资料可查看《权威指南》第二版第17、19章。

存储引擎部分

在 DAX Studio 中通过 Server Timings 窗口,了解到存储引一共执行了 3个 xmSQL 查询。

image

注意 xmSQL 与标准 SQL 不同,xmSQL 语句中的 SELECT 子句中出现的列会自动进行分组,举个例子,有 xmSQL 代码

// xmSQL
SELECT customer[country], customer[state], SUM ( customer[amount] )
FROM customer

与下面的标准 SQL 代码的作用是一样的

// 标准 SQL
SELECT customer.country, customer.state, SUM ( customer.amount )
FROM customer
GROUP BY customer.country, customer.state

为了方便后文指代,这里将这 Server Timings 窗口中的 3 次查询从上往下分别命名为 VQ1、VQ2、VQ3,每个查询的代码、作用和数据如下。

1、VQ1

( 'Dates'[Year], 'Dates'[Month Num] ) IN { ( 2020, 12 ) , ( 2019, 2 ) , ( 2020, 11 ) , ( 2019, 1 ) }​为条件,从 Dates 表中分组获取 Year 列上的值

// xmSQL VQ1
SELECT
    'Dates'[Year]
FROM 'Dates'
WHERE
     ( 'Dates'[Year], 'Dates'[Month Num] ) IN {
   
    ( 2020
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值