2014-02-17 40 views
1

背景:我一直在使用MDX,但我絕不是專家 - 尋找一些性能幫助。我正在研究SQL Server Analysis Services 2012多維數據集中的一組「數量商店授權/庫存/銷售/等等」計算度量值(MDX)。我原來的計算結果表現很好,但發現它們並不是按照我需要的方式在我的產品層次結構上進行彙總。本報告中主要使用的兩個層次是業務 - >項目和分部 - >商店。MDX - 篩選計數CROSSJOIN - 性能問題

例如,在原始MDX計算中,商店庫存量度將在「料品」級別正確執行,但不會在其上方的「業務」級別上合理計算總和。在商業層面,我們希望看到庫存商店/產品組合的總數,而不是最初看起來的明顯或最大值。

原始查詢結果:下面是它正常工作(想象這是一個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   ...    ...     ... 

QUERY需要HELP:這裏是「新的」的查詢其產生上述結果:

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] }, 

此查詢語法在一堆其他「店鋪數量銷售/缺貨/ ETC使用。「 - 在立方體中鍵入計算的度量值,只有底部的[庫存量]條件變化或鏈接附加條件。

在當前情況下,該查詢可能需要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:是」,一個條件不履行,說「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呼叫更快。

+0

這個數據也受到時間的約束,所以向維度添加一個屬性並不一定會工作......但是我想像你提到的那樣,在DSV中的事實表上考慮了一個二進制標誌。我可以嘗試並報告。 –

+0

我們繼續按照您的建議將條件建模到多維數據集中,並且工作速度提高了5倍。猜猜我們試圖對MDX過於樂觀! –

1

我相信你可以避免交叉連接以及完全過濾。嘗試使用這樣的:

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 

我想在我的立方體使用尺寸和使用面積的子公司層次。 case語句處理在業務級別查看數據的情況。基本上,CASE語句中用於所有項目名稱的成員SUM()計算單個項目名稱的值,然後彙總所有值。我相信這是你需要的。