2017-04-07 59 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討論,因爲他將能夠就可能對多維數據集設計進行的修改提供堅實的建議。