数据分析师的福音:BitMap 在 Row-Level Security 中的作用
在日常工作中,你是否遇到过这样的情况?某个 Power BI 模型在几个月内运行得非常流畅,但突然有一天,性能出现了问题。尽管模型没有任何改动,安全规则也没有调整,只是某张表的数据量超过了某个阈值,导致查询效率大幅下降。
了解 Row-Level Security 实际做了什么
Row-Level Security 在 Tabular 模型中的作用是通过 DAX 表达式附加到角色内的表上。引擎会对每一行执行该表达式(谓词),返回 TRUE 的行对角色成员可见,其他行则被隐藏,不仅在报告中看不到,在总计、COUNTROWS 等操作中也不存在。
谓词的两种类型
谓词分为两类,但你可能不会太关心它们的区别:
-
廉价谓词:列与常量或用户属性进行比较。
Geography[Country] = "Canada" -
昂贵谓词:需要查找、关系遍历或度量。
Customer[CustomerID] IN CALCULATETABLE ( VALUES ( Access[CustomerID] ), Access[User] = USERPRINCIPALNAME() )
筛选策略
当查询在活跃角色下运行时,引擎会选择三种策略之一:
- 本地筛选:如果谓词简单且可以推入扫描中,则免费执行。
- 缓存的 Bitmap:如果表足够小以构建位图。
- 逐行回调:每次调用。
位图机制详解
当谓词太复杂无法推入扫描时,引擎会一次性评估它并将其答案记录为一个位图。每个位元表示一行数据是否可见给角色成员:
- 可见 - 1
- 过滤 - 0
具体例子:
Geography[Country] = "Canada"
| 行号 | 国家 | 位元 | | ---- | ------ | --- | | 0 | CA | 1 | | 1 | US | 0 | | 2 | CA | 1 | | 3 | CA | 1 | | 4 | JP | 0 | | 5 | US | 0 | | 6 | CA | 1 | | 7 | CA | 1 |
引擎实际处理时是一个连续的位元数组,按存储段对齐,并以 64 位字节包装,以便一次读取 64 行。
Bitmap 的优化
随着表中数据的增长,BitMap 变得越来越重要。默认情况下,Bitmap 的大小增加了四倍,这意味着在复杂谓词的情况下,查询性能可以显著提升。这样就可以避免逐行回调,从而提高整体性能。
这个改进对于处理大量数据的复杂模型非常关键。如果你经常遇到查询性能下降的问题,不妨检查一下你的 Row-Level Security 调整是否已经充分利用了这一机制。





