2017-04-07 38 views
0

处理包含由多个层次结构组成的UserGroups维的SSAS多维数据集。每个层次结构都将用户分类为属于特定的组。用户可以属于多个组。在共享维上针对每层的一行快速MDX查询

尝试为维度中的每个层次结构生成一行。我想出最好的办法是:

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语句组合行时,每个额外的行似乎导致计算时间呈指数增长,而不是计算时间中所需的线性增加。

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

令人惊讶的是每一行都很慢。用户是否计数常规SUM度量?事实表有多少行?如果您只是通过组A进行了简单的用户计数查询,需要多长时间才能检索到一个单元格?收入如何?除了问题之外,还有其他计算方法吗? – GregGalloway

+0

你有改变立方体的自由度吗?多对多的UserGroup维度是有意义的。让我知道如果这是一个选项。 – GregGalloway

回答

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 
     ... 
     ... 

道歉我没有definites - 以上只是选择,可能会得到幸运!最好尽可能详细地与Greg讨论,因为他将能够就可能对多维数据集设计进行的修改提供坚实的建议。