MDX - 过滤的 CROSSJOIN 计数 - 性能问题

Posted

技术标签:

【中文标题】MDX - 过滤的 CROSSJOIN 计数 - 性能问题【英文标题】:MDX - Count of Filtered CROSSJOIN - Performance Issues 【发布时间】:2014-03-17 11:19:56 【问题描述】:

背景:我使用 MDX 已经有一段时间了,但我绝不是这方面的专家 - 寻求一些性能帮助。我正在 SQL Server Analysis Services 2012 多维数据集中处理一组“授权商店数/库存/销售/等”计算度量 (MDX)。我最初让这些计算表现良好,但发现它们并没有按照我需要的方式聚合到我的产品层次结构中。本报告中主要使用的两个层次结构是业务 -> 项目和部门 -> 商店。

例如,在原始 MDX 计算中,Stores In-Stock 度量将在“项目”级别正确执行,但不会将适当的总和汇总到其上方的“业务”级别。在业务层面,我们希望看到库存中商店/产品组合的总数,而不是最初看起来的不同或 MAX 值。

原始查询结果:这是一个正常工作的示例(假设这是一个 Excel 数据透视表):

[FILTER: CURRENT WEEK DAYS]
[BUSINESS]          [AUTH. STORES]  [STORES IN-STOCK]   [% OF STORES IN STOCK]
[+] Business One    2,416           2,392               99.01%
[-] Business Two    2,377           2,108               93.39%
    -Item 1         2,242           2,094               99.43%
    -Item 2         2,234           1,878               84.06%
    -Item 3         2,377           2,108               88.68%
    -Item N         ...             ...                 ...

固定查询结果:经过多次试验和错误,我转而使用 DESCENDANTS() 函数对两个层次结构的 CROSSJOIN() 进行过滤计数,从而产生正确的数字(如下):

[FILTER: CURRENT WEEK DAYS]
[BUSINESS]          [AUTH. STORES]  [STORES IN-STOCK]   [% OF STORES IN STOCK]
[+] Business One    215,644         149,301             93.90%
[-] Business Two    86,898          55,532              83.02%
    -Item 1         2,242           2,094               99.43%
    -Item 2         2,234           1,878               99.31%
    -Item 3         2,377           2,108               99.11%
    -Item N         ...             ...                 ...

需要帮助的查询:这是产生上述结果的“新”查询:

CREATE MEMBER CURRENTCUBE.[Measures].[Num Stores In-Stock]
AS COUNT(
    FILTER(
        CROSSJOIN(
            DESCENDANTS(
                [Product].[Item].CURRENTMEMBER,
                [Product].[Item].[UPC]        
            ),
            DESCENDANTS(
                [Division].[Store].CURRENTMEMBER,
                [Division].[Store].[Store ID]       
            )
        ),
        [Measures].[Inventory Qty] > 0
    )
), 
FORMAT_STRING = "#,#", 
NON_EMPTY_BEHAVIOR =  [Inventory Qty] , 

此查询语法用于多维数据集中的一堆其他“正在销售/缺货/等的商店数量”类型的计算度量,只有底部的 [Inventory Qty] 条件或通过链接附加条件。

在目前的情况下,此查询可能需要 2-3 分钟才能运行,这对于此报告的受众来说太长了。谁能想到一种方法来减少查询负载或帮助我重写它以提高效率?

谢谢!


2014 年 2 月 24 日更新:我们通过绕过大量涉及的 MDX 并将标志值添加到 DSV 中的命名查询来解决了这个问题。

例如,我们没有在 MDX 代码中为“销售的商店数量”执行过滤命令 - 我们只是将其添加到名为查询的事实表中......

CASE WHEN [Sales Qty] > 0 
    THEN 1 
    ELSE NULL 
END AS [Flag_Selling]

...然后我们简单地将这些度量聚合为多维数据集中的 LastNonEmpty。它们的汇总速度比完整的 MDX 查询快得多。

【问题讨论】:

【参考方案1】:

将您的条件建模到立方体中应该更快,避免缓慢的Filter 函数:

如果只有少数几个条件,请为每个条件添加一个属性,其中包含两个值,一个表示条件满足,说“cond: yes”,一个表示条件不满足,说“cond: no”。您可以在物理事实表或 DSV 的视图中定义它,或者您可以对其进行物理建模。这些属性可以直接添加到事实表中,在同一个表上定义一个维度,或者更清楚地作为从事实表引用的单独维度表。然后将您的度量定义为

CREATE MEMBER CURRENTCUBE.[Measures].[Num Stores In-Stock]
AS COUNT(
    CROSSJOIN(
        DESCENDANTS(
            [Product].[Item].CURRENTMEMBER,
            [Product].[Item].[UPC]        
        ),
        DESCENDANTS(
            [Division].[Store].CURRENTMEMBER,
            [Division].[Store].[Store ID]       
        ),
         [Flag dim].[cond].[cond: yes] 

    )
)

您甚至可以将度量定义为事实表的标准计数度量。

如果有许多条件,则可能只添加一个属性,每个条件都有一个值作为多对多关系。这会稍微慢一些,但仍然比Filter 调用快。

【讨论】:

此数据也受时间限制,因此向维度添加属性不一定会起作用......但是我考虑过像您提到的那样在 DSV 中的事实表中添加二进制标志。我可能会尝试并报告。 我们继续按照您的建议将条件建模到立方体中,它的工作速度提高了大约 5 倍。猜猜我们是不是太喜欢 MDX 了!【参考方案2】:

我相信您可以完全避免交叉连接和过滤。试试这个:

CREATE MEMBER CURRENTCUBE.[Measures].[Num Stores In-Stock]
AS
CASE WHEN [Product].[Item Name].CURRENTMEMBER IS [Product].[Item Name].[All]
THEN 
SUM(EXISTS([Product].[Item Name].[Item Name].MEMBERS,[Business].[Business Name].CURRENTMEMBER),
COUNT(
EXISTS(
    [Division].[Store].[Store].MEMBERS,
    (
        [Business].[Business Name].CURRENTMEMBER,
        [Product].[Item Name].CURRENTMEMBER
    ),
    "Measure Group Name"
)
))
ELSE
COUNT(
EXISTS(
    [Division].[Store].[Store].MEMBERS,
    (
        [Business].[Business Name].CURRENTMEMBER,
        [Product].[Item Name].CURRENTMEMBER
    ),
    "Measure Group Name"
)
)
END

我尝试使用多维数据集中的维度并使用区域-附属层次结构。 案例语句处理在业务级别查看数据的情况。基本上,SUM()CASE 语句中使用的所有项目名称成员中计算各个项目名称的值,然后将所有值相加。我相信这就是您所需要的。

【讨论】:

以上是关于MDX - 过滤的 CROSSJOIN 计数 - 性能问题的主要内容,如果未能解决你的问题,请参考以下文章

MDX Crossjoin地区和国家和总计

MDX 计算的测量计数

范围内总和计数的 MDX 计算

在特定时间获取不同的用户计数 MDX QUERY

MDX:如何将具有多个成员的元组转换为具有单个成员的元组?

以编程方式生成 MDX 行计数查询的最简单方法?