共享维度上每个层次结构的一行的快速MDX查询

时间:2017-04-07 21:10:06

标签: union mdx rows hierarchy dimension

处理包含由多个层次结构组成的UserGroups维度的SSAS多维多维数据集。每个层次结构将用户分类为属于特定组。用户可以属于多个组。

尝试为维度中的每个层次结构生成一行表格。我提出的最佳方法如下:

WITH

    MEMBER [Measures].[Group Name] AS
        CASE
            WHEN [UserGroups].[Group A].CurrentMember.MemberValue <> 'All' THEN "Group A"
            WHEN [UserGroups].[Group B].CurrentMember.MemberValue <> 'All' THEN "Group B"
            -- More user groups...
            WHEN [UserGroups].[Group T].CurrentMember.MemberValue <> 'All' THEN "Group T"
            ELSE "Error"
        END
SELECT

{[Members].[Group Name], [Measures].[User Count], [Measures].[Revenue]} ON 0,

Order(
    UNION(
         [UserGroups].[Group A].&[True] *
        {[UserGroups].[Group B].[All]} *
        -- More user groups...
        {[UserGroups].[Group T].[All]},


         [UserGroups].[Group A].[All] *
        {[UserGroups].[Group B].&[True]} *
        -- More user groups...
        {[UserGroups].[Group T].[All]},

        -- A bunch more blocks so that there is one for each row.

         [UserGroups].[Group A].[All] *
        {[UserGroups].[Group B].[All]} *
        -- More user groups...
        {[UserGroups].[Group T].&[True]}
    ),
)
ON 1

FROM [Finances];

这成功生成了预期的表:

                    Group Name  User Count  Revenue
All  All  ... True  Group T     90          1800
...  ...  ... ...   ...         ...         ...
All  True ... All   Group B     20          400
True All  ... All   Group A     10          100

但是,查询速度很慢。任何给定的行可以在大约30秒内单独计算。使用UNION语句组合行时,每个附加行似乎都会导致计算时间呈指数级增长,而不是计算时间所需的线性增长。

  • 为什么观察到这种增加的时间?
  • 有没有办法指示底层引擎单独计算每一行?
  • 是否有更好的方法来发出此查询?

1 个答案:

答案 0 :(得分:0)

我猜你已经尝试重新排列查询 - 如果你从SELECT中取出UNION(...)并在WITH子句中使它成为一个命名SET会有帮助吗?

WITH
    SET [RowSet] AS
       UNION(
         [UserGroups].[Group A].&[True] *
        {[UserGroups].[Group B].[All]} *
        -- More user groups...
        {[UserGroups].[Group T].[All]},


         [UserGroups].[Group A].[All] *
        {[UserGroups].[Group B].&[True]} *
        -- More user groups...
        {[UserGroups].[Group T].[All]},

        -- A bunch more blocks so that there is one for each row.

         [UserGroups].[Group A].[All] *
        {[UserGroups].[Group B].[All]} *
        -- More user groups...
        {[UserGroups].[Group T].&[True]}
    )
    MEMBER [Measures].[Group Name] AS
        CASE
            WHEN [UserGroups].[Group A].CurrentMember.MemberValue <> 'All' THEN "Group A"
            WHEN [UserGroups].[Group B].CurrentMember.MemberValue <> 'All' THEN "Group B"
            -- More user groups...
            WHEN [UserGroups].[Group T].CurrentMember.MemberValue <> 'All' THEN "Group T"
            ELSE "Error"
        END
SELECT

  {[Members].[Group Name], [Measures].[User Count], [Measures].[Revenue]} ON 0,

  Order(
    [RowSet],
)
ON 1
FROM [Finances];

ORDER功能的目的是什么?我看不到你的订单了吗?

再次只是在黑暗中拍摄,但我想有时我注意到使用UNION和使用+运算符之间的效率差异 - 所以另一个选项:

WITH
    SET [RowSet] AS
       {
         [UserGroups].[Group A].&[True] *
        {[UserGroups].[Group B].[All]} *
        -- More user groups...
        {[UserGroups].[Group T].[All]}
       }
      +
       {
         [UserGroups].[Group A].[All] *
        {[UserGroups].[Group B].&[True]} *
        -- More user groups...
        {[UserGroups].[Group T].[All]}
       }

        -- A bunch more blocks so that there is one for each row.
      +
       {
         [UserGroups].[Group A].[All] *
        {[UserGroups].[Group B].[All]} *
        -- More user groups...
        {[UserGroups].[Group T].&[True]}
       }
    MEMBER [Measures].[Group Name] AS
      ...
      ...

道歉我没有定义 - 以上只是可能会幸运的选项!最好尽可能详细地与Greg讨论,因为他将能够为您提供有关可能修改立方体设计的可靠建议。