2

SQL Server Analysis Services 2008 R2 Enterprise Editionキューブを参照するMDXクエリがあり、機能の観点から、必要なデータを正確かつ正確に返します。ただし、このクエリの実行には5〜10分かかります。これは、SSRSレポート内でこのクエリを実行するエンドユーザーには使用できません。

クエリは次のとおりです。

With Member [Measures].[CurrentPaidAmount] as 
Sum ( 
     Tail(nonempty(descendants([Valuation Date].[DateHierachy].currentmember,4),[Measures].[SaleCount]),1),
[Measures].[CurrentTotalPaidAmt] 
    ) 
Member [Measures].[PreviousPeriodPaidAmount] as 
Sum ( 
     Tail(descendants([Valuation Date].[DateHierachy].currentmember.prevmember,4),1), 
     [Measures].[CurrentTotalPaidAmt] 
     ) 
Member [Measures].[YTDCurrentPaidAmount] as 
([Measures].[CurrentPaidAmount] - [Measures].[PreviousPeriodPaidAmount]) 
select non empty 
    ( {[Valuation Date].[DateHierachy].[Year]}, {[Valuation Date].[Year].children}, 
      {[Valuation Date].[Month].[All]}, {[DimLocation].[State].[All]}, 
      {[DimSeller].[Store].children}, {[DimProduct].[ProductCode].children}, 
      {[DimProgram].[ProgramLine].children ) on rows, 
 [Measures].[YTDCurrentPaidAmount] on columns 
from 
    [CB_Sales]

この基礎となるファクトテーブルには、[合計支払額]メジャーが累積的に格納されます。つまり、月の最終日に、時間の開始以降に特定の製品に支払われた合計金額が計算されます。これは、各月末に、その月の合計支払額が前月の金額に加算されて、時間の初めから問題の製品のすべての支払額の総計が作成されることを意味します。

私の要件は、個々の年ごとにのみ、各製品に支払われる合計金額を計算することです。

次のサンプルデータセットについて考えてみます。このデータセットには、特定の製品の現在までの合計支払額がリストされています。


2010年12月製品A:$ 25.00

2011年11月-製品A:$ 50.00

2011年12月-製品A:$ 100.00

2012年1月-製品A:$ 150.00

2012年2月-製品A:$ 160.00

2012年3月-製品A:$ 200.00


上記の製品Aの2011暦年のみに支払われた合計金額を取得したい場合は、2010年12月現在の製品Aの現在までに支払われた合計金額($ 25.00)を取得し、この金額を合計から差し引きます。 2011年12月現在の支払額($ 100.00)。

2つの値を引くと、75.00ドルの差が生じます。

($ 100.00-$ 25.00)= $ 75.00

これは、2011暦年内にのみ製品Aに合計75.00ドルが支払われたことを示します。

そうは言っても、上記のMDXクエリに戻ると、この計算を実行するために2つの計算メンバーを作成しました。

メンバー(1):

[メジャー]。[CurrentPaidAmount]

この計算されたメンバーは、[Valuation Date]。[DateHierachy]。[Year]属性の現在のメンバーに基づいて、問題の現在の暦年に記録された最後の空でない合計金額を取得します。合計金額が記録される先月の現在の2012暦年は2012年6月であるため、計算されたメンバーは、日付階層内の[6月]2012月のメンバーが合計支払額である特定の月であることを識別するのに十分賢い必要があります。ドルはから取られるべきです。

このメンバーを表形式のレポートに表示するため、問題の日付ディメンションの[Year]属性を返すことが重要です。

したがって、計算されたメジャーに次のセットを含めました。これは、結果セット内でクライアントに返されるものに基づいて現在の年の値を取得し、問題の暦年内の最終日を取得するまで日付階層を下に移動します。以下に示すように、有効な合計支払額があります。

Tail(nonempty(descendants([Valuation Date].[DateHierachy].currentmember,4),[Measures].[SaleCount]),1),

私の推論は、ユーザーが接続されたレポート内のすべての年を選択した場合、毎年、この特定の計算されたメンバーは、問題の暦年の最後の空でない合計金額を取得し、それを前年から差し引いて取得できるようにするというものでした問題の暦年内にのみ発生した支払額の合計。

これで、上記の完全なMDXクエリは、実行時に正しいデータを返します。実行には永遠に時間がかかりますが、実行には5〜10分以上かかります。基になるファクトテーブルには、6,400万件のレコードが含まれています。

奇妙なことに、このように最初に計算されたメンバー内のセットからnonempty()句を削除すると、変更されたクエリの実行に30秒しかかかりません。

With Member [Measures].[CurrentPaidAmount] as 
Sum (
      Tail(descendants([Valuation Date].[DateHierachy].currentmember,4),1), [Measures].[CurrentTotalPaidAmt] 
    )

計算されたメンバーが日付メンバーと[Measures]。[SaleCount]メジャーとの各共通部分を評価する必要があるため、nonempty()句がクエリのパフォーマンスを低下させていると推測できます。

上記のクエリを書き直して、数分ではなく30秒以内に、より良く、より速く、より効率的に実行できる方法はありますか?

キューブにデフォルトの集計が適用されており、いくつかのキューブパーティションに分割されています。

私はMDXの初心者なので、あなたの提案をいただければ幸いです。

お時間をいただきありがとうございます!

4

3 に答える 3

0

ファクトテーブルに非累積支払額を格納できる場合は、直接[Measures].[YTDCurrentPaidAmount]保持し、との計算を回避し[Measures].[CurrentPaidAmount]ます[Measures].[PreviousPeriodPaidAmount]

于 2012-07-11T06:33:15.297 に答える
0

私は MDX のまったくの初心者ですが、NON EMPTY 句を削除する際のパフォーマンスの問題に関する私自身の問題を解決しようとしたときに、あなたの質問に対する潜在的な解決策に出会いました。メンバーの計算場所の基本情報ペインで NON EMPTY BEHAVIOR を設定してみてください。よろしく

カール

于 2012-07-19T08:42:34.550 に答える
0

既存のものを混ぜると、NONEMPTY に対してブーストを得ることができる場合があります。

http://cwebbbi.wordpress.com/2009/03/31/existing-and-nonempty/

そこで彼は変わる

COUNT(NONEMPTY(
NONEMPTY(
EXISTING [Customer].[Customer].[Customer].MEMBERS
, [Measures].[Internet Sales Amount])
, ([Measures].[Internet Sales Amount], [Date].[Calendar].CURRENTMEMBER.PREVMEMBER))
)

COUNT(EXISTING  
NONEMPTY(
NONEMPTY(
[Customer].[Customer].[Customer].MEMBERS
, [Measures].[Internet Sales Amount])
, ([Measures].[Internet Sales Amount], [Date].[Calendar].CURRENTMEMBER.PREVMEMBER))
)

速度が 8 倍になります。

日付ディメンションでこれに遭遇するのは奇妙に思えます - 通常、少なくとも他のディメンション (顧客や製品など) と比較して、多くの日付はありません。あなたの日付次元はどれくらいですか? 不必要に未来や過去に行きますか?

使用状況に基づく最適化を調べ、SSAS サーバーのプロパティを設定して、MDX 呼び出しを指定したデータベースに記録し、ウィザードを実行して、それに基づいて一連の集計を作成します。次に、集計をパーティションに割り当て、正しく覚えていれば「インデックスの処理」...

http://www.sqlservercentral.com/articles/Analysis+Services+(SSAS)/usagebasedoptimizationinssas2005/2419/

于 2012-07-11T13:44:54.163 に答える