패스 순서 및 계산 순서 이해(MDX)
MDX 스크립트 결과로 계산될 때 큐브는 사용되는 여러 계산 관련 기능에 따라 여러 계산 단계를 거칠 수 있습니다. 이러한 각 단계를 계산 패스라고 합니다.
계산 패스는 계산 패스 번호라는 서수 위치로 참조될 수 있습니다. 큐브의 모든 셀 계산을 완전히 마치는 데 필요한 계산 패스 개수를 큐브의 계산 패스 깊이라고 합니다.
팩트 테이블 및 쓰기 저장(writeback) 데이터는 패스 0에만 영향을 줍니다. 스크립트는 패스 0 이후의 데이터를 채우며 스크립트에서 각 대입식 및 계산 문은 새로운 패스를 만듭니다. MDX 스크립트 외부에서 절대 패스 0에 대한 참조는 큐브의 스크립트에서 만든 마지막 패스를 참조합니다.
계산 멤버는 모든 패스에서 생성되지만 식은 현재 패스에 적용됩니다. 이전 패스에는 계산 측정값이 포함되지만 Null 값이 들어 있습니다.
계산 순서
계산 순서는 식을 완료하는 경우 계산의 우선 순위를 확인합니다. 단일 패스 내에서 계산 순서는 다음 두 가지를 확인합니다.
MicrosoftSQL ServerAnalysis Services에서 차원, 멤버, 계산 멤버, 사용자 지정 롤업 및 계산 셀을 평가하는 순서
Analysis Services에서 사용자 지정 멤버, 계산 멤버, 사용자 지정 롤업 및 계산 셀을 계산하는 순서
계산 순서가 가장 높은 멤버가 우선 순위가 가장 높습니다.
[!참고]
집계 함수는 이러한 우선 순위에서 제외됩니다. 집계 함수의 계산 멤버는 교차하는 계산 측정값보다 계산 순서가 낮습니다.
계산 우선 순위
계산 우선 순위는 현재 셀에서 정의된 식의 값을 얻는 순서를 정의합니다. 계산 우선 순위는 다음 알고리즘에 따라 확인됩니다.
CL(계산 목록)은 현재 셀이나 그 아래의 세분성에서 모든 계산으로부터 만들어집니다.
CL의 계산은 HW(Highest Wins) 또는 CW(Closest Wins)로 분류됩니다.
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보다 낮은 계산 순서 값이 사용됩니다. 이러한 낮은 계산 순서 값은 계산 멤버가 사용자 지정 롤업 수식보다 먼저 계산되도록 하므로 잘못된 결과가 발생할 수 있습니다.
계산 순서 만들기 및 바꾸기
큐브 디자이너의 계산 창에서 계산 순서를 바꿔서 계산 멤버 및 계산 셀에 대한 계산 순서를 바꿀 수 있습니다.
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 하나만 있습니다. 계산 멤버가 하나뿐이기 때문에 큐브에 계산 멤버가 사용되지 않으면 계산 순서가 문제가 되지 않습니다.
이 MDX 쿼리는 다음 표와 비슷한 결과 집합을 생성합니다.
|
수입 |
비용 |
---|---|---|
상반기 |
5000 |
4200 |
하반기 |
8000 |
7000 |
연간 차이 |
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 쿼리는 다음 표와 비슷한 약간 다른 결과 집합을 생성합니다.
|
수입 |
비용 |
순수입 |
---|---|---|---|
상반기 |
5000 |
4200 |
0.16 |
하반기 |
8000 |
7000 |
0.125 |
결과 집합에서 첫 번째 쿼리와 두 번째 쿼리의 차이는 계산 멤버의 배치 차이로 인해 비롯됩니다. 첫 번째 쿼리에서 계산 멤버는 두 번째 쿼리에 표시된 COLUMNS 축이 아니라 ROWS 축의 일부입니다. 이러한 배치 차이는 두 계산 멤버를 단일 MDX 쿼리로 조합하는 다음 쿼리에서 중요해집니다.
쿼리 3—조합된 연간 차이 및 순수입 계산
이 마지막 쿼리에서는 이전 예에서의 두 쿼리를 단일 MDX 쿼리로 조합하며 계산 순서가 중요해집니다. 올바른 순서로 계산되도록 보장하기 위해 SOLVE_ORDER 키워드를 사용하여 계산이 발생하는 순서를 정의합니다.
SOLVE_ORDER 키워드는 MDX 쿼리 또는 CREATE MEMBER 명령의 계산 멤버에 대한 계산 순서를 지정합니다. SOLVE_ORDER 키워드에 사용된 정수 값은 상대적이며 0부터 시작할 필요가 없으며 연속적일 필요도 없습니다. 이 값은 MDX에서 단순히 더 큰 값의 멤버 계산으로부터 파생된 값에 따라 멤버를 계산하도록 지정합니다. 계산 멤버가 SOLVE_ORDER 키워드 없이 정의된 경우 해당 계산 멤버의 기본값은 0입니다.
예를 들어 처음 두 쿼리 예에서 사용된 값을 조합할 경우 두 계산 멤버인 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 수식을 사용하여 문제의 셀을 계산합니다. 이 중첩된 계산의 결과는 다음 표에 표시된 것과 같습니다.
|
수입 |
비용 |
순수입 |
---|---|---|---|
상반기 |
5000 |
4200 |
0.16 |
하반기 |
8000 |
7000 |
0.125 |
연간 차이 |
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 수식을 사용하여 셀을 계산합니다.
|
수입 |
비용 |
순수입 |
---|---|---|---|
상반기 |
5000 |
4200 |
0.16 |
하반기 |
8000 |
7000 |
0.125 |
연간 차이 |
3000 |
2800 |
-0.035 |
이 쿼리에는 Net Income 데이터와 함께 Year Difference 수식이 사용되기 때문에 공유 셀에 대한 수식은 다음 계산과 비슷합니다.
((8000 - 7000) / 8000) - ((5000 - 4200) / 5000) = -0.035
또는
0.125 - 0.16 = -0.035
기타 고려 사항
계산 멤버, 사용자 지정 롤업 수식 또는 계산 셀이 포함된 차원 수가 높은 큐브에서는 특히 계산 순서를 다루기가 매우 복잡할 수 있습니다. Analysis Services에서 MDX 쿼리를 계산할 때 Analysis Services는 MDX 쿼리에 지정된 큐브의 차원을 비롯하여 지정된 패스 내에 관련된 모든 사항에 대한 계산 순서 값을 고려합니다.