了解行程順序與解決順序 (MDX)
當 Cube 做為 MDX 指令碼的計算結果時,Cube 會根據所使用的各種計算相關功能來進行多個計算階段。每個階段都稱為一個計算行程。
計算行程可以是序數位置,稱為計算行程數目。完整計算 Cube 中所有資料格所需的計算行程數目稱為 Cube 的計算行程深度。
事實資料表和回寫資料只會影響行程 0。行程 0 之後,指令碼會擴展資料;指令碼中每個指派和計算陳述式都會建立新的行程。在 MDX 指令碼之外,對絕對行程 0 的參考會參考指令碼為 Cube 所建立的最後行程。
導出成員會在所有行程建立,但運算式只會在目前行程套用。先前的行程包含導出量值,不過會是 Null 值。
解決順序
解決順序決定在運算式發生競爭事件時,計算的優先權。在單一行程內,解決順序決定兩件事情:
MicrosoftSQL ServerAnalysis Services 評估維度、成員、導出成員、自訂積存和導出資料格的順序。
Analysis Services 評估自訂成員、導出成員、自訂積存和導出資料格的順序。
擁有最高解決順序的成員優先。
[!附註]
此優先順序的例外狀況是彙總函數。具有彙總函數的導出成員,其解決順序比任何交集的導出量值還低。
計算優先順序
計算優先順序會定義在目前的資料格中,針對定義的運算式取得值的順序。計算優先順序會根據下列演算法來解析:
在目前資料格的資料粒度 (或更低) 上,從所有計算中建立計算清單 (CL)。
CL 中的計算分成:最高獲勝 (HW) 或最接近獲勝 (CW)
CW 為自訂積存、一元運算子、局部加總量值、凍結
HW 則是所有其他的計算
排序的計算清單 (OCL) 是從依照行程排序的所有 HW 中建立
其餘的每一個 CW
OCL 中的每一個計算 (C) (從最高到最低)
如果 CW 比較接近目前的資料格而不是 C,請在 OCL 中插入 CW,並繼續下一個 CW
如果 CW 位於比 C 更高的行程上,請在 OCL 中插入 CW,並繼續下一個 CW
繼續下一個 C
如果 OCL 中的最高計算不在目前資料格的相同資料粒度上,則使用彙總函數計算彙總值
解決順序值和優先順序
解決順序值的範圍可以從 -8181 到 65535。在此範圍中,某些解決順序值是對應到特定的計算種類,如下表所示。
計算 |
解決順序 |
---|---|
自訂成員公式 |
-5119 |
一元運算子 |
-5119 |
視覺化總計計算 |
-4096 |
其他所有計算 (若沒有特別指定) |
0 |
強烈建議您在設定解決順序值時只使用正整數。如果您指定比上表中解決順序值還低的值,計算行程可能會變得無法預測。例如,導出成員的計算會收到一個低於預設自訂積存公式值 -5119 的解決順序值。這類低的解決順序值會造成導出成員的計算早於自訂積存公式,所以會產生不正確的結果。
建立與變更解決順序
在 [Cube 設計師] 的 [計算窗格] 上,您可以變更計算的順序,來變更導出成員和導出資料格的解決順序。
在 MDX 中,您可以使用 SOLVE_ORDER 關鍵字來建立或變更導出成員與導出資料格。
解決順序範例
為了方便說明解決順序的可能複雜性,下列 MDX 查詢以兩個查詢開始,而個別查詢沒有解決順序的問題。當這兩個查詢結合成一個查詢時,就需要解決順序。
查詢 1—收益和費用的差異
在第一個 MDX 查詢,若要查看每半年的收益和費用差異,請建立一個簡單的 MDX 查詢,如以下範例所示:
WITH
MEMBER [Time].[Year Difference] AS
[Time].[2nd half] - [Time].[1st half]
SELECT
{ [Account].[Income], [Account].[Expenses] } ON COLUMNS,
{ [Time].[1st half], [Time].[2nd half], [Time].[Year Difference] } ON ROWS
FROM Financials
在此查詢中,只有一個導出成員 Year Difference。因為只有一個導出成員,只要 Cube 不使用任何導出成員,就沒有解決順序的問題。
此 MDX 查詢產生類似下表的結果集。
|
Income |
Expenses |
---|---|---|
1st half |
5000 |
4200 |
2nd half |
8000 |
7000 |
Year Difference |
3000 |
2800 |
查詢 2—扣除費用後的淨收益百分比
在第二個查詢,若要查看每半年扣除費用後的淨收益百分比,請使用以下 MDX 查詢:
WITH
MEMBER [Account].[Net Income] AS
([Account].[Income], [Account].[Expenses]) / [Account].[Income]
SELECT
{ [Account].[Income], [Account].[Expenses], [Account].[Net Income] } ON COLUMNS,
{ [Time].[1st half], [Time].[2nd half] } ON ROWS
FROM Financials
此 MDX 查詢和前一個查詢類似,只有一個導出成員 Net Income,因此也沒有任何解決順序的問題。
此 MDX 查詢產生類似下表,但有些微差異的結果集。
|
Income |
Expenses |
Net Income |
---|---|---|---|
1st half |
5000 |
4200 |
0.16 |
2nd half |
8000 |
7000 |
0.125 |
第一個查詢和第二個查詢之間的結果集差異,在於導出成員的位置差異。在第一個查詢中,導出成員是 ROWS 座標軸的一部份,而不是第二個查詢中的 COLUMNS 座標軸。此種位置的差異在下一個查詢 (結合單一 MDX 查詢的兩個導出成員) 中就變得很重要。
查詢 3—結合年度差異和淨收益的計算
在結合上述兩個範例到單一 MDX 查詢的最終查詢,解決順序就變得很重要。若要確定以正確的順序進行計算,請使用 SOLVE_ORDER 關鍵字定義計算順序。
SOLVE_ORDER 關鍵字指定 MDX 查詢中導出成員或 CREATE MEMBER 命令的解決順序。和 SOLVE_ORDER 關鍵字並用的整數值是相對值,不需要從零開始,也不需要連續。此數值只是告知 MDX 根據有較高值的成員計算所得出的值來導出成員。如果導出成員沒有以 SOLVE_ORDER 關鍵字定義,該導出成員的預設值為零。
例如,如果您結合前兩個範例查詢中使用的計算,兩個導出成員 Year Difference 和 Net Income 會在 MDX 查詢範例之結果資料集中的單一資料格中產生交集。決定 Analysis Services 如何評估此資料格的唯一方式,就是解決順序。用來建立此資料格的公式會根據兩個導出成員的解決順序,來產生不同的結果。
首先,請嘗試結合以下 MDX 查詢中前兩個查詢所使用的計算:
WITH
MEMBER [Time].[Year Difference] AS
'[Time].[2nd half] - [Time].[1st half],
SOLVE_ORDER = 1
MEMBER [Account].[Net Income] AS
'([Account].[Income] - [Account].[Expenses]) / [Account].[Income]',
SOLVE_ORDER = 2
SELECT
{ [Account].[Income], [Account].[Expenses], [Account].[Net Income] } ON COLUMNS,
{ [Time].[1st half], [Time].[2nd half], [Time].[Year Difference] } ON ROWS
FROM Financials
在此結合的 MDX 查詢範例中,Net Income 擁有最高的解決順序,所以當兩個運算式有交集時,會優先處理它。Analysis Services 會使用 Net Income 公式來評估有問題的資料格。此巢狀計算的結果,如下表所示。
|
Income |
Expenses |
Net Income |
---|---|---|---|
1st half |
5000 |
4200 |
0.16 |
2nd half |
8000 |
7000 |
0.125 |
Year Difference |
3000 |
2800 |
0.066 |
共用資料格中的結果是以 Net Income 的公式為基礎。也就是說,Analysis Services 會計算含有 Year Difference 資料之共用資料格的結果,產生下列公式 (為了清楚起見,結果為四捨五入):
((8000 - 5000) - (7000 - 4200)) / (8000 - 5000) = 0.066
或
(3000 - 2800) / 3000 = 0.066
但是,如果您在 MDX 查詢中切換導出成員的解決順序,Analysis Services 會以不同方式計算共用資料格的結果。以下結合的 MDX 查詢改變了導出成員的解決順序:
WITH
MEMBER [Time].[Year Difference] AS
'[Time].[2nd half] - [Time].[1st half],
SOLVE_ORDER = 2
MEMBER [Money].[Net Income] AS
'([Money].[Income] - [Money].[Expenses]) / [Money].[Income]',
SOLVE_ORDER = 1
SELECT
{ [Money].[Income], [Money].[Expenses], [Money].[Net Income] } ON COLUMNS,
{ [Time].[1st half], [Time].[2nd half], [Time].[Year Difference] } ON ROWS
FROM TestCube
當導出成員的解決順序切換後,Analysis Services 就會使用 Year Difference 公式來評估資料格,如下表所示。
|
Income |
Expenses |
Net Income |
---|---|---|---|
1st half |
5000 |
4200 |
0.16 |
2nd half |
8000 |
7000 |
0.125 |
Year Difference |
3000 |
2800 |
-0.035 |
因為此查詢使用含有 Net Income 資料的 Year Difference 公式,所以共用資料格的公式會類似以下計算:
((8000 - 7000) / 8000) - ((5000 - 4200) / 5000) = -0.035
或
0.125 - 0.16 = -0.035
其他考量
若 Cube 有大量的維度,並牽涉到導出成員、自訂積存公式或導出資料格時,處理解決順序會是非常複雜的問題。當 Analysis Services 評估 MDX 查詢時,Analysis Services 會考慮給定行程內牽涉到的所有項目 (包括 MDX 查詢中指定之 Cube 的維度) 的解決順序值。