OLAPの中央値のオーバークロック

この投稿は、OLAPキューブの中央値を計算するときにパフォーマンスの問題が発生した人向けです。

OLAPテクノロジの主な利点の1つは、データベースにアクセスするときに結果を取得する速度です。 計算はその場で行われます。 ただし、中央値ではそれほど単純ではありません。

参考:中央値は中程度のビューです。 これは、昇順でソートされた一連の値の中央にある値です。 たとえば、多数の値{1、2、5、6、9}の場合、中央値は5です。



MicrosoftのOLAPサーバー-SSAS 2008(SQL Server Analysis Services)の例の状況を考慮してください。

SSASでは、MDX Median関数を使用して中央値を計算することをお勧めします。 これを使用して、計算メンバーを作成し、計算で使用できます。



さまざまなソースから取得した労働市場の空席に関するデータを分析するOLAPキューブを設計するタスクに直面しました。 空室の総数は約1,000万でした。 中央値を使用して、平均値を決定するために中央値を実装しました。 キューブでの作業中に「オンザフライ」で計算が機能しませんでした。 ただし、他の集計、たとえば空室数はすぐに考慮されました。

問題は、量や量などの集計が「集計」されることです。キューブを更新するときは事前に計算され、データを要求するときにサーバーは既製の結果を返します。 中央値の場合、サーバーはその値を事前に計算しませんが、キューブにアクセスするたびに値を計算します。



サンプルレポートを考えてみましょう。





2011年の専門「Developer 1C」では、8,354の空きが見つかりました。 この専門分野の給与の中央値を計算するには、サーバーは次の操作を実行する必要があります:レポートのこのセルに関連するすべての値を選択し、給与の値で並べ替え、一連の値(タプル)の中央にある値を決定します。 そして各セルに対して。 したがって、レポートの実行時間は大幅に増加します。 同時にメインタイムは正確にソートに行きます。



解決策



中央値を計算するための値は、OLAPキューブの作成に基づいたデータウェアハウスファクトテーブルから選択されます。 ファクトテーブルが給与値で事前にソートされると仮定した場合はどうなりますか。 次に、各セルの値を並べ替える必要はありません。 各セルの要素数を決定し、行の中央にある要素の数を計算するだけです。 この要素の値は中央値になります。



計算メンバーを作成するためのコード:



//    CREATE MEMBER CURRENTCUBE.[measures].[AdvCount] AS Count(NonEmpty([Advertisement].[ID].members,[Measures].[Salary]) as AdvSet), VISIBLE = 0 ; //     CREATE MEMBER CURRENTCUBE.[Measures].[MedianReal] AS ([measures].[AdvCount]-1) * 50 / 100, VISIBLE = 0; CREATE MEMBER CURRENTCUBE.[Measures].[MedianInt] AS Int([Measures].[MedianReal]), VISIBLE = 0; CREATE MEMBER CURRENTCUBE.[Measures].[MedianFrac] AS [Measures].[MedianReal]- [Measures].[MedianInt], VISIBLE = 0; //  CREATE MEMBER CURRENTCUBE.[Measures].[MedianLow] AS (NonEmpty([Advertisement].[ID].members,[Measures].[Salary]).Item([Measures].[MedianInt]).Item(0),[Measures].[Salary]), VISIBLE = 0; CREATE MEMBER CURRENTCUBE.[Measures].[MedianHigh] AS (NonEmpty([Advertisement].[ID].members,[Measures].[Salary]).Item([Measures].[MedianInt] + 1).Item(0),[Measures].[Salary]), VISIBLE = 0; CREATE MEMBER CURRENTCUBE.[Measures].[Salary Median] AS ([Measures].[MedianLow] * [Measures].[MedianFrac]) +([Measures].[MedianHigh] * (1 - [Measures].[MedianFrac])), FORMAT_STRING = "# ### ### ##0;-# ### ### ##0", VISIBLE = 1 , ASSOCIATED_MEASURE_GROUP = 'Advertisement';
      
      







このコードでは、タプルに偶数個の要素が含まれる状況を考慮します。 この場合、中央値は系列の中央にある2つの値の算術平均として計算されます。 タスクが絶対的な正確さを必要としない場合、この場合、中央値の左または右の値を考慮することができます。 これを行うには、上記のコードをわずかに変更する必要がありますが、これにより計算時間がさらに短縮されます。



ファクトテーブルを事前にソートする方法について説明します。 元のファクトテーブルがあり、そのデータが時間とともに蓄積されるとします。 このテーブルのコピーを作成し、必要な値でソートされた元のテーブルのデータをそこに挿入します。



サンプルSQLクエリ:



 INSERT INTO CopyBasicTable SELECT * FROM BasicTable ORDER BY ValueField
      
      







この操作は、OLAPキューブを更新する前に毎回実行する必要があります。 もちろん、この方法には重大なマイナスがあります-大量のデータがある場合、操作時間はかなり長くなります。 ただし、比較的小さなボリュームの場合、この方法は非常に適しています。 同様に、パーセンタイルと四分位数を計算できます。



All Articles