DAX中CALCULATE为何不推荐使用表过滤器而要选用多列过滤器?
DAX中使用表过滤器替代多列过滤器的问题说明
我们通常说表过滤器是次优写法,核心问题集中在性能、结果正确性、可维护性三个维度,结合你给出的示例说明如下:
1. 性能损耗明显
表过滤器的本质是迭代整表逐行判断条件,而CALCULATE原生支持的多列布尔谓词会触发DAX引擎的存储引擎级优化,直接对列做批量筛选,不需要逐行迭代,大表场景下性能差距可达数倍到数十倍。
- 以
Big Sales Amount度量值为例:
次优表过滤器写法需要迭代整个Sales事实表,逐行计算Sales[Quantity] * Sales[Net Price]再做判断,若Sales有千万级数据量,会产生千万次行级别计算。
改用多列谓词写法后,计算和筛选都在存储引擎层批量完成,不需要逐行迭代,性能大幅提升:-- 次优写法 Big Sales Amount := CALCULATE ( [Sales Amount], FILTER ( Sales, Sales[Quantity] * Sales[Net Price] > 1000 ) )-- 最优写法 Big Sales Amount := CALCULATE ( [Sales Amount], Sales[Quantity] * Sales[Net Price] > 1000 )
2. 容易意外修改筛选上下文,导致结果错误
大部分新手写表过滤器时,没有意识到ALL、整表引用等写法会清除外部筛选上下文,最终返回不符合预期的结果。
- 以
Red or Contoso Sales度量值为例:
次优写法中用了ALL('Product'[Color], 'Product'[Brand]),会直接清除外部所有对Color和Brand列的筛选,如果你报告中加了品牌切片器选了Fabrikam,这个度量值依然会返回所有红颜色或者Contoso品牌的销售额,完全忽略切片器的选择。
改用多列谓词写法后,默认会在现有外部筛选上下文的基础上追加筛选,你选了-- 次优写法 Red or Contoso Sales := CALCULATE ( [Sales Amount], FILTER ( ALL ( 'Product'[Color], 'Product'[Brand] ), 'Product'[Color] = "Red" || 'Product'[Brand] = "Contoso" ) )Fabrikam切片器时,返回的就是Fabrikam品牌下颜色为红的销售额,符合常规业务逻辑;如果确实需要清除外部筛选,只需要额外加REMOVEFILTERS即可,灵活度更高。-- 最优写法 Red or Contoso Sales := CALCULATE ( [Sales Amount], 'Product'[Color] = "Red" || 'Product'[Brand] = "Contoso" )
3. 代码语义模糊,维护成本高
表过滤器写法代码更长,嵌套层级更多,新手很难快速理解筛选逻辑;原生多列谓词写法简洁直白,修改筛选条件时也不容易出错。
内容的提问来源于stack exchange,提问作者variable
相关产品推荐
相关产品推荐

