白杨商业智能工作室
#技术分享#Power BI#最佳实践

告别DISTINCTCOUNT性能焦虑

· 白杨BI工作室

你有没有遇到过这种情况:Power BI 报表里一个简单的去重计数,数据量一大就卡成 PPT? 明明只是数一下有多少笔交易、多少个客户,结果刷新要等半天,点个筛选还要转圈圈。 如果你正在为 DISTINCTCOUNT 的性能头疼,这篇文章能帮你省下不少时间和算力。

告别DISTINCTCOUNT性能焦虑

你有没有遇到过这种情况:Power BI 报表里一个简单的去重计数,数据量一大就卡成 PPT?

明明只是数一下有多少笔交易、多少个客户,结果刷新要等半天,点个筛选还要转圈圈。

如果你正在为 DISTINCTCOUNT 的性能头疼,这篇文章能帮你省下不少时间和算力。

为什么 DISTINCTCOUNT 这么慢?

在零售模型里,数交易笔数是最常见的需求:三月份卖了多少单?新西兰有多少笔?其中多少单买了 T 恤?

大多数人第一反应就是写:

Transactions = DISTINCTCOUNT ( FactTransaction[TransactionID] )

结果正确,但在大事实表上,这是你能让存储引擎做的最昂贵操作之一。

DISTINCTCOUNT 需要扫描所有行,然后去重,这个过程极其消耗资源。

一个被低估的替代方案

今天要分享的建模技巧,能让你用 COUNTROWS 回答大部分这类问题,并且显著减少真正需要去重时的计算量。

它不会完全替代 DISTINCTCOUNT,但能让你在不需要的时候不为其买单,在需要的时候给它更少的数据去处理。

这个思路不仅适用于零售,保险理赔、制造工单、医疗就诊、物流托运、客服通话……只要你想数某个属于"自然父级"的实例数量,都适用。

动手前先做 30 秒检查

在开始建模之前,先拿到两个数字:事实表的行数,以及你要去重的那一列的基数。

用 SQL 查:

SELECT
    COUNT(*)                       AS FactRows,
    COUNT(DISTINCT TransactionID)  AS DistinctTransactions
FROM dbo.FactTransaction;

或者在 DAX 里直接算:

EVALUATE
ROW (
    "FactRows",             COUNTROWS ( FactTransaction ),
    "DistinctTransactions", DISTINCTCOUNT ( FactTransaction[TransactionID] )
)

这两个数字的比值,决定了这个技巧能帮你多少。

核心思路:行数与去重值的差值

设行数为 R,去重值为 D,那么多余的行数 E = R - D。

每笔交易如果有超过一行(比如明细行),就说明存在重复。而这个 E 值,就是你可以用 COUNTROWS 直接"免费"拿到的部分。

具体怎么做?

假设你的事实表 FactTransaction 中,每个 TransactionID 对应多行(比如一行一个商品明细)。

  1. 先建一个交易维度表,只包含唯一的 TransactionID
  2. 在事实表与维度表之间建立一对多关系(维度表一端是"一")
  3. 计数度量直接用 COUNTROWS(TransactionDimension)

这样,当你按时间、地区、产品筛选时,只要筛选条件能传递到维度表,COUNTROWS 就能正确返回交易笔数,而无需去重。

只有当筛选条件直接作用在事实表明细行上(比如某个商品的子类),才需要回到 DISTINCTCOUNT。

效果立竿见影

  • 大部分常规交易计数:COUNTROWS 直接搞定,性能提升数倍
  • 少数需要真实去重的场景:由于维度表已经大大减少了行数,DISTINCTCOUNT 也快得多
  • 存储引擎的压力明显下降,报表响应更流畅

国内用户怎么看

这个技巧在电商、新零售场景特别适用——订单表动辄几千万行,每个订单多行明细,用 COUNTROWS 替代 DISTINCTCOUNT 后,报表刷新速度和交互体验都能明显改善。

而且这个思路对 Vertipaq 引擎友好,不需要额外配置,纯建模技巧就能见效。

什么时候不该用?

  • 当你的事实表本身每行就是唯一实例(比如流水号),没有自然父级时
  • 当筛选条件总是直接作用于明细行,无法通过维度表传递时
  • 当数据模型已经很复杂,增加维度表可能让关系链变长时

总结

DISTINCTCOUNT 不是敌人,但你需要学会在合适的场景用 COUNTROWS 来绕开它。

先算算你的 R 和 D,看看差值有多大,然后设计一个交易维度表,你会发现 Power BI 的性能还有不少潜力可挖。

如果你也想优化自己的模型,不妨从这两个数字开始。

相关文章

Power BI 和 Microsoft Fabric 的 Databricks ADBC 连接器正式发布

Power BI 和 Microsoft Fabric 的 Databricks ADBC 连接器正式发布

微软正在把 Power Query 连接器的底层驱动从 ODBC 迁到 ADBC,这次轮到 Databricks。适用于 Power BI 和 Microsoft Fabric 的 Databricks ADBC 连接器已正式 GA(Generally Available,正式发布)。

#技术分享#Power BI#Fabric#语义模型
Power BI 2026 年 10 月功能摘要

Power BI 2026 年 10 月功能摘要

距离上一次九月更新才过去没多久,而且当时还赶上了欧洲 Microsoft Fabric + SQL 社区大会,更新量已经不小。

#技术分享#Power BI#Fabric#Copilot
Microsoft Data Factory 的 Amazon Redshift V2 连接器

Microsoft Data Factory 的 Amazon Redshift V2 连接器

微软正在对 Amazon Redshift 连接器进行重要升级,底层驱动将从旧版切换至全新的 Amazon Redshift ODBC 2.x。

#技术分享#Power BI#Fabric
F2容量跑通完整报表方案

F2容量跑通完整报表方案

很多团队一提到 Microsoft Fabric,第一反应就是:F2 这种小容量能干嘛? 跑个 Demo 都嫌卡,更别说承载一套完整的报表解决方案了。

#技术分享#Power BI#最佳实践
近似去重反而更慢?

近似去重反而更慢?

做 DAX 性能优化的人,看到 `APPROXIMATEDISTINCTCOUNT` 这个新函数,第一反应多半是:终于有办法治 `DISTINCTCOUNT` 这个性能杀手了。 但最近一轮实测下来,结论有点打脸——在某些场景下,近似去重反而比精确去重更慢。

#Power BI#最佳实践
近似去重计数:快但准吗?

近似去重计数:快但准吗?

9 月 Power BI 更新后,Import 模式和 Direct Lake 模式的语义模型开始支持 `ApproximateDistinctCount()` 这个 DAX 函数。 我在一个 14 亿行的 Direct Lake 语义模型上做了测试,数据来自纽约出租车样本。

#Power BI#最佳实践
有问题?加企业微信 1 对 1 交流 👇
➕ 添加企业微信
备注「白杨」优先通过 · 数据洞察与智能决策
企业微信
企业微信
备注「白杨」优先通过