新闻活动

阅读公司最新动态、市场活动、媒体报道等最新公告。

Power BI | 为啥你的 Power BI 刷新巨慢?

23/07/2026

数据源慢?服务器性能不够?
为什么你的报表刷新巨慢,可能是你没搞懂查询折叠

✦ 本期核心问题

不是数据源慢,是你把1200万行全拉到本地算。

01、刷新6分钟,谁都不承认

小李负责的销售日报,每天早上8:30自动刷新。三个月前只要40秒。现在6分12秒。

他找IT。IT看了下服务器:「SQL Server资源使用率不到15%,不是我们这边的问题。」

他找DBA。DBA跑了一下SQL Profiler,截图发过来:「你的Power BI在跑一条 SELECT * FROM SalesOrder,扫了全表1200万行。数据库不慢,是你每次刷新都在把整张表搬进Power BI。」

小李打开Power Query编辑器,点开「销售订单」查询,数了一下:22个应用步骤。筛选、去重、分组、合并、加自定义列、改数据类型……每一步他都觉得「必须做」。

问题就出在这里。不是数据库慢,是数据根本没在数据库里算。

02、Power Query的每一步,不是你想的那样

Power Query连接SQL Server这类数据源时,有一个机制叫查询折叠。

简单说:你把M语言写的转换步骤——筛选行、选择列、分组聚合、排序——Power Query把它翻译成一条SQL语句,直接发给数据库执行。数据库算完,只把结果返回给你。

折叠时:1200万行筛选到30万行 → 数据库干,传30万行过来。 ✅

但如果折叠断了呢?Power Query会把1200万行全拉进本地内存,然后用自己的引擎一条条筛。1200万行全部走网卡、进内存、被Mashup引擎处理。

这就是阿豪的6分钟从哪来的。

不是数据库慢,是数据根本没在数据库里算。

03、一个步骤就能毁掉整条链

查询折叠的规则很残酷:一旦某一步不可折叠,它后面的所有步骤——哪怕本身可以折叠——也都废了。整条链从那个断点开始,全部在本地执行。

小李打开查询折叠指示器(Power Query编辑器 → 视图 → 勾选「查询折叠指示器」),看到:

步骤 折叠状态
导航 已折叠
删除其他列 已折叠
筛选日期 ≥ 2026-01-01 已折叠
添加自定义列(提取月份) 未折叠
筛选金额 > 1000 未折叠
分组汇总 未折叠
…后续所有步骤 全部未折叠

踩坑提示

断点在第4步:他加了一个自定义列 Month = Date.Month([OrderDate])。这个M函数没有SQL等价物,折叠断了。从这一步开始,后面所有的筛选、分组、去重——全是Power BI在本地吭哧吭哧算。

SQL Server收到的实际查询是什么?DBA截到的就是那条:

SELECT * FROM [SalesOrder]
WHERE [OrderDate] >= '2026-01-01'

前3步折叠成了WHERE条件。第4步一断,第5步的 金额 > 1000 根本没进SQL——它是Power BI把全部数据拉到本地之后才筛的。

04、三步修好:重排、替代、推到源

小李做了三件事:

STEP 01:重排步骤——把能折叠的操作移到断点前面

他原本的步骤顺序:

导航 → 删列 → 筛选日期 → 添加自定义列 → 筛选金额 → 分组

调整后:

导航 → 删列 → 筛选日期 → 筛选金额 → 分组 → 添加自定义列

金额筛选和分组现在排在自定义列前面。SQL Server收到的查询变成了:

SELECT [OrderDate], [Amount], [ProductID], [Region]
FROM [SalesOrder]
WHERE [OrderDate] >= '2026-01-01' AND [Amount] > 1000
GROUP BY [OrderDate], [ProductID], [Region]

结果:数据库先筛再分组,返回的结果集只有2万行。自定义列在2万行上做,毫秒级。

STEP 02:替换M函数——用可折叠的写法替代不可折叠的

他原来写 Date.Month([OrderDate]) 是为了在报表里按月筛选。这个需求完全可以在数据源端解决:

-- 在SQL Server建一个视图,把月份作为独立列
CREATE VIEW vw_SalesOrder AS
SELECT *, MONTH(OrderDate) AS OrderMonth
FROM SalesOrder

Power Query直接连视图,OrderMonth 是一个普通整数列,折叠不受影响。

STEP 03:推到源——把复杂逻辑交给数据库

小李还有一个步骤是 Table.AddColumn 用了一串嵌套if做客户分级。这玩意在Power Query里不可折叠,但用SQL的 CASE WHEN 写完全没问题。他在视图里加了这个字段,Power Query只负责拉现成数据。

修完后,他重新看折叠指示器:

步骤 折叠状态
导航 已折叠
删除其他列 已折叠
筛选日期 ≥ 2026-01-01 已折叠
筛选金额 > 1000 已折叠
分组汇总 已折叠
添加自定义列(从视图取) 已折叠

全绿。

第二天早上8:30,刷新用了51秒。

05、一个你可能每天都在犯的错

小李的问题不是技术不行,是他把Power Query当成ETL工具在用。

Power Query的定位是数据接入层——把数据从源系统接进来、做必要的列筛选和简单转换。不是让你在1200万行上做字符串拼接、日期运算、嵌套条件判断。

一个简单的判断标准:步骤超过15步 + 3个以上自定义列 = 折叠大概率已断。

把复杂计算推回数据源。SQL视图、存储过程、甚至直接在数据库里加计算列——任何你能在数据源端完成的事情,都比在Power Query里做强一百倍。

06、查一下你自己的模型

现在就打开你的Power BI Desktop,做三件事:

1、 启用折叠指示器。文件 → 选项和设置 → 选项 → Power Query编辑器 → 勾选「查询折叠指示器」。然后打开Power Query,看每个查询最后一步的图标颜色。

2、 找到第一个红色步骤。它就是你的断点。看它是什么操作——自定义列?日期函数?文本处理?把能折叠的步骤移到它前面。

3、 右键最后一步,看「查看原生查询」是灰色还是可用。灰色 = 整条链都没折叠。可用 = 至少最后一步之前都在折叠。点开看看SQL长什么样——如果是一个简单的 SELECT * 没带WHERE,说明你的筛选根本没进数据库。

07、记住一句话

查询折叠不是优化技巧,是Power Query连接关系型数据库的基本工作方式。折叠断了,就等于你主动选择了「把所有数据拉到本地再算」。

这句话值6分钟——报表的6分钟。

Copyright © 2013-2026 深圳悦策科技有限公司 粤ICP备14039318号