Performance 如何在Daxstudio中检查哪个DAX查询具有更好的性能?

Performance 如何在Daxstudio中检查哪个DAX查询具有更好的性能?,performance,dax,daxstudio,Performance,Dax,Daxstudio,如何使用检查两个DAX查询中哪一个具有更好的性能。在本例中,查询返回完全相同的结果。然而,统计数据有所不同,显示出不明确的暗示。通过对这两个问题的比较,我们能掌握哪些有用的信息 比较查询统计信息摘要: +-------------------------+------------+---------+---------+ | | | Query 1 | Query 2 | +-------------------------+

如何使用检查两个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 )
)
EVALUATE
ADDCOLUMNS (
    VALUES ( ThisTable[Product] ),
    "FilterLookup", MAXX (
        FILTER ( SearchTable, SearchTable[Product] = ThisTable[Product] ),
        SearchTable[Category]
    )
)
该查询具有以下统计信息:

和查询计划:

第二项查询。

EVALUATE
ADDCOLUMNS (
    VALUES ( ThisTable[Product] ),
    "FilterLookup",
    VAR LookupKey = ThisTable[Product]
    RETURN
        CALCULATE ( MAX ( SearchTable[Category] ), SearchTable[Product] = LookupKey )
)
EVALUATE
ADDCOLUMNS (
    VALUES ( ThisTable[Product] ),
    "FilterLookup", MAXX (
        FILTER ( SearchTable, SearchTable[Product] = ThisTable[Product] ),
        SearchTable[Category]
    )
)
统计数据:

查询计划:

问题涉及:

您可以下载包含示例数据的pbix文件:


由于固定的开销成本,很难从一个小数据集推断出一个大数据集的性能,因此我建议在更大的数据表上进行测试


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

由于固定的开销成本,很难将性能从一个小数据集推断为一个大数据集,因此我建议在较大的数据表上进行测试


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

当数据集非常小时,您无法从DAX Studio中真正分辨出来,但在大多数情况下,具有最简单查询计划的查询将是最快的。查询#1就是这种情况,这确实是您的情况下最快的查询(忽略~20毫秒以下的所有时间测量-因为它不可靠,因为数据集太小)

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

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

编辑:我没有注意到“苹果”在
搜索表[产品]
列中出现了两次。这将导致上述对
LOOKUPVALUE(…)
的调用失败,因为它无法为
SearchTable[Category]
找到一个明确的值,当数据集如此之小时,您无法从DAX Studio中真正分辨出来,但在大多数情况下,具有最简单查询计划的查询将是最快的。查询#1就是这种情况,这确实是您的情况下最快的查询(忽略~20毫秒以下的所有时间测量-因为它不可靠,因为数据集太小)

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

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

编辑:我没有注意到“苹果”在
搜索表[产品]
列中出现了两次。这将导致上述对
LOOKUPVALUE(…)
的调用失败,因为它无法为
SearchTable[Category]
找到明确的值。我想了解一下我们可以从Daxstudio中获得哪些有用的信息。统计和查询计划中的信息对我来说并不清楚。我还认为
MAXX
会比
MAX
慢。但是Daxstudio统计数据与这个信念相矛盾:-)我是说你不能从你所做的实验中看出很多东西(除非你可能非常擅长阅读查询计划)。我敢打赌,如果集合较大(
MAX
可能更快),结果会有所不同。MAX在内部执行MAXX(如果应用于单个列),因此这里MAXX和MAX的性能完全相同。如果有上下文转换,情况就不同了。谢谢你,拉多。我也在更大的数据集上尝试过这个方法,它看起来确实像是
MAXX
版本更快,但如果我在
CALCULATE
中使用
FILTER
而不是简单的布尔过滤器(我想这就是OP的第一个过滤器变慢的原因)。Alexis,你能解释一下你的发现吗?这意味着什么:“MAXX版本更快,但如果我在计算中使用过滤器而不是简单的布尔过滤器,则不会更快”?请把这句话写在你的答案里,我想知道我们能从达斯图迪奥那里得到什么有用的信息。统计和查询计划中的信息对我来说并不清楚。我还认为
MAXX
会比
MAX
慢。但是Daxstudio统计数据与这个信念相矛盾:-)我是说你不能从你所做的实验中看出很多东西(除非你可能非常擅长阅读查询计划)。我敢打赌,如果集合较大(
MAX
可能更快),结果会有所不同。MAX在内部执行MAXX(如果应用于单个列),因此这里MAXX和MAX的性能完全相同。如果有上下文转换,情况就不同了。谢谢你,拉多。我也在更大的数据集上尝试过这个方法,它看起来确实像是
MAXX
版本更快,但如果我在
CALCULATE
中使用
FILTER
而不是简单的布尔过滤器(我想这就是OP的第一个过滤器变慢的原因)。Alexis,你能解释一下你的发现吗?这意味着什么:“MAXX版本更快,但如果我在计算中使用过滤器而不是简单的布尔过滤器,则不会更快”?也许放