【问题标题】:How to check in Daxstudio which DAX query has better performance?如何在 Daxstudio 中检查哪个 DAX 查询具有更好的性能?
【发布时间】:2020-05-09 23:59:44
【问题描述】:

如何使用Daxstudio 检查两个 DAX 查询中哪一个的性能更好。在示例中,查询返回完全相同的结果。然而,统计数据不同,显示出不明确的提示。从两个查询的比较中我们可以掌握哪些有用的信息?

比较查询统计摘要:

+-------------------------+------------+---------+---------+
|                         |            | Query 1 | Query 2 |
+-------------------------+------------+---------+---------+
| Server timings          | Total      |       7 |       5 |
|                         | SE CPU     |       0 |       0 |
|                         | FE         |       6 |       4 |
|                         | SE         |       1 |       1 |
|                         | SE Queries |       3 |       2 |
|                         | SE Cashe   |       0 |       0 |
+-------------------------+------------+---------+---------+
| Query plan, no of lines | physical   |       7 |      28 |
|                         | logical    |      13 |       9 |
+-------------------------+------------+---------+---------+
  • 第二个查询更快,但计划繁琐且更长。 2 次扫描。
  • 第一个查询具有更长的服务器计时,但查询计划更简洁、更短。 3 次扫描。

因此,服务器计时有利于第二个查询,但其复杂的查询计划引起了人们的关注。了解统计信息和查询计划后,如果 SearchTable 有数百万行,我们可以期待什么?我们不应该喜欢更简单的查询计划吗,因为未来 DAX 优化可能会发生变化,对他们有利?

样本数据。我们有两个表 SearchTable 和 ThisTable:

SearchTable = 
DATATABLE (
    "Category", STRING,
    "Product", STRING,
    "Amount", INTEGER,
    {
        { BLANK ()      , "apple"       , 1 },
        { "Fruits"      , "apple"       , 1 },  -- watch out for multiple apples!
        { "Yummy Fruits", "apple"       , 2 },
        { "Fruits"      , "banana"      , 4 },
        { "Fruits"      , "wolfberry"   , 5 },
        { "Fruits"      , "cherry"      , 3 },
        { "Vegetables"  , "carrot"      , 3 },
        { "Vegetables"  , "potato"      , 1 },
        { "Vegetables"  , "onion"       , 7 },
        { "Fruits"      , "cherry"      , 3 }        
    }
)
---
ThisTable = 
DATATABLE (
    "Product", STRING,
    {
        { "apple" },
        { "banana" },
        { "blackberry" },
        { "carrot" },
        { "cherry" },
        { "onion " },
        { "potato" },
        { "watermelon" },
        { "wolfberry" }
    }
)

第 1 个查询。

EVALUATE
ADDCOLUMNS (
    VALUES ( ThisTable[Product] ),
    "FilterLookup",
    VAR LookupKey = ThisTable[Product]
    RETURN
        CALCULATE ( MAX ( SearchTable[Category] ), SearchTable[Product] = LookupKey )
)

查询具有以下统计信息:

及查询计划:

第 2 个查询。

EVALUATE
ADDCOLUMNS (
    VALUES ( ThisTable[Product] ),
    "FilterLookup", MAXX (
        FILTER ( SearchTable, SearchTable[Product] = ThisTable[Product] ),
        SearchTable[Category]
    )
)

统计:

查询计划:

问题与:

DAX lookup first non blank value in unrelated table

您可以下载带有示例数据的 pbix 文件:

DAX lookup top 1 value.pbix

【问题讨论】:

    标签: performance dax daxstudio


    【解决方案1】:

    您无法从 DAX Studio 中真正看出,什么时候数据集如此之小,但在大多数情况下,具有最简单查询计划的查询将是最快的。查询 #1 就是这种情况,这确实是您情况下最快的查询(忽略低于 ~20 毫秒的所有时间测量值 - 因为它不可靠,因为数据集太小了)。

    另外,我想补充一点,以下查询应该提供相同的结果,并且速度更快,查询计划比您的两个查询更简单:

    ADDCOLUMNS(
        ThisTable,
        "FilterLookup",
            LOOKUPVALUE(SearchTable[Category], SearchTable[Product], ThisTable[Product])
    )
    

    编辑:我没有注意到“apple”在SearchTable[Product] 列中出现了两次。这将导致上述对LOOKUPVALUE(...) 的调用失败,因为它无法找到SearchTable[Category] 的明确值。

    【讨论】:

    • (1) 谢谢。在大多数情况下,当 Alberto 和 Marco(我不介绍他们)演示优化技巧时,他们会简化查询计划,然后执行时间就会下降。但这里有不同的提示。您建议最简单的查询计划。扫描次数呢?第二个查询只有 2 次扫描,而第一个查询有 3 次扫描。 (2) 您提供的代码不适用于示例数据。它会引发错误:A table of multiple values was supplied where a single value was expected. 请参阅stackoverflow.com/q/59310106/1903793
    • (1) 最小化 SE 查询(扫描)的数量本身并不是目标。最好有 10 个 SE 查询,每个查询只返回很少的行(后期实现),而不是单个 SE 查询返回大量行(早期实现)。但同样 - 对于这样的查询,在一个只有 10 条记录的数据集上,你是否做一件事或另一件事并不重要。
    • (2) 我没有注意到您的搜索表有两次“苹果”,这就是失败的原因。要使 LOOKUPVALUE 起作用,它必须能够返回明确的结果 - 换句话说,搜索列应该只包含唯一值。
    • (2) 这就是为什么我将第一个初始问题设置为“查找第一个非空白值”。但事实证明,MAX 和 MAXX 比 Karl Anka 在此处提出的解决方案要快得多:stackoverflow.com/a/59318268/1903793 我开始使用 Daxstudio 测量性能,这就是我们在这里的原因。
    • 好的 - 你应该让我们知道查询计划和 SE 查询在你的原始查询上是什么样子的,我假设它扫描一个更大的数据集,因为不可能得出任何关于优化的结论您在这篇文章中展示的小样本数据集。另外——你不能假设公式引擎会为一个小数据集生成相同的查询计划,就像它为一个真实的大数据集生成的一样。根据所涉及数据的实际基数和统计数据,可能会进行许多内部优化。
    【解决方案2】:

    由于固定的开销成本,很难将小型数据集的性能外推到大型数据集,因此我建议在更大的数据表上进行测试。

    一般来说,您希望尽可能避免使用像 MAXX 这样的迭代器,而尽可能使用 MAX,因为后者具有引擎优化。很少有规则在优化查询方面是通用的,因此鉴于您显示的数据,这是一个相当基于意见的问题。

    【讨论】:

    • 我想了解我们可以从 Daxstudio 获得哪些有用的信息。来自统计信息和查询计划的信息对我来说并不清楚。我还认为MAXX 会比MAX 慢。但 Daxstudio 的统计数据与这种信念相矛盾:-)
    • 我是说你不能从你所做的实验中看出很多东西(除非你很擅长阅读查询计划)。我敢打赌,如果使用更大的集合,结果会有所不同(MAX 可能会更快)。
    • MAX 在内部执行 MAXX(如果应用于单个列),因此这里 MAXX 和 MAX 将具有完全相同的性能。如果有上下文转换,情况就不同了。 dax.guide/max
    • 感谢@RADO。我也尝试过使用更大的数据集,它看起来确实像MAXX 版本更快,但如果我在CALCULATE 中使用FILTER 而不是简单的布尔过滤器(我认为这就是OP 的第一个过滤器)慢。)。
    • Alexis,你能解释一下你的发现吗?这是什么意思:“MAXX 版本更快,但如果我在 CALCULATE 中使用 FILTER 而不是简单的布尔过滤器则不是”?也许把它放在你的答案中,请
    猜你喜欢
    • 2019-05-06
    • 2011-11-24
    • 2015-03-14
    • 1970-01-01
    • 2012-12-01
    • 2011-12-02
    • 2017-08-09
    • 1970-01-01
    相关资源
    最近更新 更多