前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >优化Power BI中的Power 优化Power BI中的Power Query合并查询效率,Part 1:通过删除列来实现

优化Power BI中的Power 优化Power BI中的Power Query合并查询效率,Part 1:通过删除列来实现

作者头像
陈学谦
发布2020-06-17 15:09:05
4.4K0
发布2020-06-17 15:09:05
举报
文章被收录于专栏:学谦数据运营学谦数据运营

本篇文章主体部分为翻译Chris Webb的一篇文章。

合并查询在Power Query中是很成熟的应用,相当于SQL中的各种JOIN(抽时间会写几篇SQL的join,算是SQL的小核心)。但同时,在Power Query中合并查询是一个常见的影响刷新效率的因素。在我的工作中,经常会遇到对一些非文件夹性质的数据源进行合并查询操作,所以我一直在想,有没有办法可以对其进行优化。最近我正好做了一些测试,希望这些结果能够帮助到大家。

以下是我的测试数据源,只有一个CSV格式的文件,100万行7列数字格式的数据A, B C, D, E, F 和G:

在本次测试当中,我使用了SQL Server 事件探查器去计算刷新的时间。以下两个事件的持续时间是我们关注的重点:

  • Progress Report End/25 Execute SQL
  • Progress Report End/17 Read Data

第一个我想搞清楚的问题是:

表中列的数量是否影响合并查询时的效率?

首先,我对这个CSV文件创建了两个连接,按照惯例,将第一行转为标题,将7列数字全都定义为整数格式。M代码也是非常简洁明了:

代码语言:javascript
复制
let
  Source = Csv.Document(
    File.Contents("C:\NumbersMoreColumns.csv"), 
    [Delimiter = ",", Columns = 7, 
     Encoding = 65001, QuoteStyle = QuoteStyle.None]
  ),
  #"Promoted Headers" = 
   Table.PromoteHeaders(Source, [PromoteAllScalars = true]),
  #"Changed Type" = Table.TransformColumnTypes(
    #"Promoted Headers", 
    {
      {"A", Int64.Type}, 
      {"B", Int64.Type}, 
      {"C", Int64.Type}, 
      {"D", Int64.Type}, 
      {"E", Int64.Type}, 
      {"F", Int64.Type}, 
      {"G", Int64.Type}
    }
  )
in
  #"Changed Type"

将两个查询都取消加载,然后建立第三个查询,使用Table.NestedJoin函数将两个查询进行内联结:

代码语言:javascript
复制
let
  Source = Table.NestedJoin(
   First, {"A"}, Second, {"A"}, 
   "Second", JoinKind.Inner),
  #"Expanded Second" = Table.ExpandTableColumn(
    Source, 
    "Second", 
    {"A", "B", "C", "D", "E", "F", "G"}, 
    {"Second.A", "Second.B", "Second.C", 
     "Second.D", "Second.E", "Second.F", "Second.G"}
  )
in
  #"Expanded Second"

当我刷新这个查询时,在SQL Server 事件探查器中可以看到两个过程的持续时间:

  • Progress Report End/25 Execute SQL – 40 秒
  • Progress Report End/17 Read Data – 56 秒

相当慢。

但是如果我们合并的表都只有一列呢,还会像合并7列那么慢吗?

为了这样测试,我在两个查询中又添加了一个步骤,删除B-G列,只剩下A列:

代码语言:javascript
复制
let
  Source = Csv.Document(
    File.Contents("C:\NumbersMoreColumns.csv"), 
    [Delimiter = ",", Columns = 7, 
     Encoding = 65001, QuoteStyle = QuoteStyle.None]
  ),
  #"Promoted Headers" = 
   Table.PromoteHeaders(Source, [PromoteAllScalars = true]),
  #"Changed Type" = Table.TransformColumnTypes(
    #"Promoted Headers", 
    {
      {"A", Int64.Type}, 
      {"B", Int64.Type}, 
      {"C", Int64.Type}, 
      {"D", Int64.Type}, 
      {"E", Int64.Type}, 
      {"F", Int64.Type}, 
      {"G", Int64.Type}
    }
  ),
  #"Removed Other Columns" = 
   Table.SelectColumns(#"Changed Type", {"A"})
in
  #"Removed Other Columns"

接着,我又重新建了一个查询,只合并两个表的一列:

代码语言:javascript
复制
let
  Source = Table.NestedJoin(
   First, {"A"}, Second, {"A"}, 
   "Second", JoinKind.Inner),
  #"Expanded Second" = 
   Table.ExpandTableColumn(Source, "Second", {"A"}, {"Second.A"})
in
  #"Expanded Second"

查询结束后,SQL Server 事件探查器显示:

  • Progress Report End/25 Execute SQL – 9 秒
  • Progress Report End/17 Read Data – 1 秒

很明显,快多了。

不过我转念一想:如果是直接查询的表的大小影响了性能,而不是由于合并查询呢?所以,我在合并查询的最后一步又添加了一步:

代码语言:javascript
复制
let
  Source = Table.NestedJoin(
   First, {"A"}, Second, {"A"}, 
   "Second", JoinKind.Inner),
  #"Expanded Second" = 
   Table.ExpandTableColumn(Source, "Second", {"A"}, {"Second.A"}),
  #"Counted Rows" = Table.RowCount(#"Expanded Second")
in
  #"Counted Rows"

接下来我又重新运行了一遍上面的查询。我的想法是,合并查询最终只返回一个单独的值,也就是数据量大小,所以不会成为增加查询时间的因素。

以下是运行以上查询时使用7列的表进行查询的时间:

  • Progress Report End/25 Execute SQL – 56 秒
  • Progress Report End/17 Read Data – 0 秒

以下是运行以上查询时使用1列的表进行查询的时间:

  • Progress Report End/25 Execute SQL – 14 秒
  • Progress Report End/17 Read Data – 0 秒

以上的确能够得出结论:合并查询时,列数的多少的确会影响效率,

以上还揭示了:在以上两个查询中,读取数据是立刻发生的,几乎不占用时间,相比之下,最开始的两次查询中读取数据的时间甚至要比执行SQL语句花费的时间更长。

为什么表的列数会影响合并查询的性能的?因为合并查询是发生在内存当中,所以合并查询的表越大,内存需求就越大,也就需要更多的分页,因为超过了分页文件256MB的限制。当每个表中含有两列时合并查询会提交584MB数据,而如果时合并查询两个7列的表,最大会提交3GB的数据。

所以最后,我们可以从容地得出结论:

在合并查询前,去掉不必要的列,的确可以提升刷新效率。

其实合并查询删掉不必要的列,可以有两种方式,一种是如今天说的,在合并查询之前删掉;另外,我们也可以在合并查询后对不需要的列进行删除。

从逻辑上来看,合并查询后再删除列,很明显要比今天说的浪费时间。

然而事实真的是如此吗?

还记得我们之前说过的微软的产品无处不在的节省算力吗?

节省算力:提前知晓同一字段的所有筛选器,先进行合并,再进行计算,避免对同一字段重复计算。

这就是下一篇的内容了。

参考文档:

Chris Webb

https://blog.crossjoin.co.uk/2020/05/31/optimising-the-performance-of-power-query-merges-in-power-bi-part-1

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-06-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 PowerBI生命管理大师学谦 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档