Ssas 快速动态命名集计算
我有一个长而复杂的查询,包含大量计算和条件,但主要结构如下所示:Ssas 快速动态命名集计算,ssas,mdx,olap,query-performance,mdxstudio,Ssas,Mdx,Olap,Query Performance,Mdxstudio,我有一个长而复杂的查询,包含大量计算和条件,但主要结构如下所示: WITH MEMBER [Id1] AS [Level].[Level1].CurrentMember.Member_Key MEMBER [Id2] AS [Level].[Level2].CurrentMember.Member_Key MEMBER [Level].[Level1].[FirstSet] AS NULL MEMBER [Level].[Level1].[SecondSet] AS NULL SET [Set
WITH
MEMBER [Id1] AS [Level].[Level1].CurrentMember.Member_Key
MEMBER [Id2] AS [Level].[Level2].CurrentMember.Member_Key
MEMBER [Level].[Level1].[FirstSet] AS NULL
MEMBER [Level].[Level1].[SecondSet] AS NULL
SET [Set 1] AS {some processed set members}
SET [Set 2] AS {some other processed set members}
SET [Common CrossJoin Set] AS [Level].[Level2].Members
MEMBER [Calculated Measure 1] AS
IIF([Level].[Level].CurrentMember.Member_Key = 'FirstSet',
SUM(existing [Set 1]),
IIF([Level].[Level].CurrentMember.Member_Key = 'SecondSet',
SUM(existing [Set 2]),
SUM([Measures].[Measure1]) * 15
)
)
MEMBER [Calculated Measure 2] AS
IIF([Level].[Level].CurrentMember.Member_Key = 'FirstSet',
SUM(existing [Set 1]),
IIF([Level].[Level].CurrentMember.Member_Key = 'SecondSet',
SUM(existing [Set 2]),
SUM([Measures].[Measure2]) * 20
)
)
SELECT
{ [Id1], [Id2], [Calculated Measure 1], [Calculated Measure 2]} ON COLUMNS,
{ ([Common CrossJoin Set], [Level].[Level1].[FirstSet]),
([Common CrossJoin Set], [Level].[Level1].[SecondSet])
} ON ROWS
FROM [Cube]
结果表如下所示:
WITH
MEMBER [Id1] AS [Level].[Level1].CurrentMember.Member_Key
MEMBER [Id2] AS [Level].[Level2].CurrentMember.Member_Key
MEMBER [Level].[Level1].[FirstSet] AS NULL
MEMBER [Level].[Level1].[SecondSet] AS NULL
SET [Set 1] AS {some processed set members}
SET [Set 2] AS {some other processed set members}
SET [Common CrossJoin Set] AS [Level].[Level2].Members
MEMBER [Calculated Measure 1] AS
IIF([Level].[Level].CurrentMember.Member_Key = 'FirstSet',
SUM(existing [Set 1]),
IIF([Level].[Level].CurrentMember.Member_Key = 'SecondSet',
SUM(existing [Set 2]),
SUM([Measures].[Measure1]) * 15
)
)
MEMBER [Calculated Measure 2] AS
IIF([Level].[Level].CurrentMember.Member_Key = 'FirstSet',
SUM(existing [Set 1]),
IIF([Level].[Level].CurrentMember.Member_Key = 'SecondSet',
SUM(existing [Set 2]),
SUM([Measures].[Measure2]) * 20
)
)
SELECT
{ [Id1], [Id2], [Calculated Measure 1], [Calculated Measure 2]} ON COLUMNS,
{ ([Common CrossJoin Set], [Level].[Level1].[FirstSet]),
([Common CrossJoin Set], [Level].[Level1].[SecondSet])
} ON ROWS
FROM [Cube]
║ ---------------║ ---------------------------║ Id1║ Id2║ 措施1║ 措施2║
║ L2成员║ L1.FirstSet成员║ L2-1║ L1-8║ 1.║ 5.║
║ L2成员║ L1.FirstSet成员║ L2-2║ L1-9║ 2.║ 6.║
║ L2成员║ L1.第二组成员║ L2-3║ L1-98║ 3.║ 7.║
║ L2成员║ L1.第二组成员║ L2-4║ L1-99║ 4.║ 8.║
结果是正确的,但查询速度非常慢(>4秒)。我的实际查询更大,并且包含很多这样的集合和度量,所以问题似乎出在现有的函数和总体结构中,从而阻止引擎执行内部优化
这种解决方案是错误和丑陋的,但我如何重写它并更快地获得相同的结果呢?我怀疑瓶颈是因为当您使用
Iif
时,两个逻辑分支都不是NULL
,因此您没有得到块模式计算:这是使用Iif
的更好方法:Iif(someBoolean,X,Null)
或Iif(someBoolean,Null,X)
但不幸的是,在您的情况下,这两种类型中都不能有Null
也许您可以尝试实现Mosha建议的这种模式来替换Iif
:
WITH
MEMBER Measures.[Normalized Cost] AS [Measures].[Internet Standard Product Cost]
CELL CALCULATION ScopeEmulator
FOR '([Promotion].[Promotion Type].&[No Discount],measures.[Normalized Cost])'
AS [Measures].[Internet Freight Cost]+[Measures].[Internet Standard Product Cost]
MEMBER [Ship Date].[Date].RSum AS Sum([Ship Date].[Date].[Date].MEMBERS), SOLVE_ORDER=10
SELECT
[Promotion].[Promotion Type].[Promotion Type].MEMBERS on 0
,[Product].[Subcategory].[Subcategory].MEMBERS*[Customer].[State-Province].[State-Province].MEMBERS ON 1
FROM [Adventure Works]
WHERE ([Ship Date].[Date].RSum, Measures.[Normalized Cost])
这是关于优化Iif
的博文:
看看你的一个计算结果——这一个:
MEMBER [Calculated Measure 1] AS
IIF([Level].[Level].CurrentMember.Member_Key = 'FirstSet',
SUM(existing [Set 1]),
IIF([Level].[Level].CurrentMember.Member_Key = 'SecondSet',
SUM(existing [Set 2]),
SUM([Measures].[Measure1]) * 15
)
)
我认为我们可以首先将其分解为:
MEMBER [Measures].[x] AS SUM(existing [Set 1])
MEMBER [Measures].[y] AS SUM(existing [Set 2])
MEMBER [Measures].[z] AS SUM([Measures].[Measure1]) * 15
MEMBER [Calculated Measure 1] AS
IIF([Level].[Level].CurrentMember IS [Level].[Level].[Level].[FirstSet],
[Measures].[x],
IIF([Level].[Level].CurrentMember IS [Level].[Level].[Level].[SecondSet],
[Measures].[y],
[Measures].[z]
)
)
现在尝试应用Mosha的模式(我以前没有尝试过,所以您需要进行相应的调整)
我怀疑瓶颈是因为当您使用
Iif
时,两个逻辑分支都不是NULL
,因此您没有得到块模式计算:这是使用Iif
的更好方法:Iif(someBoolean,X,NULL)
或Iif(someBoolean,NULL,X)
但不幸的是,在您的情况下,这两个选项中都不能有null
也许您可以尝试实现Mosha建议的这种模式来替换Iif
:
WITH
MEMBER Measures.[Normalized Cost] AS [Measures].[Internet Standard Product Cost]
CELL CALCULATION ScopeEmulator
FOR '([Promotion].[Promotion Type].&[No Discount],measures.[Normalized Cost])'
AS [Measures].[Internet Freight Cost]+[Measures].[Internet Standard Product Cost]
MEMBER [Ship Date].[Date].RSum AS Sum([Ship Date].[Date].[Date].MEMBERS), SOLVE_ORDER=10
SELECT
[Promotion].[Promotion Type].[Promotion Type].MEMBERS on 0
,[Product].[Subcategory].[Subcategory].MEMBERS*[Customer].[State-Province].[State-Province].MEMBERS ON 1
FROM [Adventure Works]
WHERE ([Ship Date].[Date].RSum, Measures.[Normalized Cost])
这是关于优化Iif
的博文:
看看你的一个计算结果——这一个:
MEMBER [Calculated Measure 1] AS
IIF([Level].[Level].CurrentMember.Member_Key = 'FirstSet',
SUM(existing [Set 1]),
IIF([Level].[Level].CurrentMember.Member_Key = 'SecondSet',
SUM(existing [Set 2]),
SUM([Measures].[Measure1]) * 15
)
)
我认为我们可以首先将其分解为:
MEMBER [Measures].[x] AS SUM(existing [Set 1])
MEMBER [Measures].[y] AS SUM(existing [Set 2])
MEMBER [Measures].[z] AS SUM([Measures].[Measure1]) * 15
MEMBER [Calculated Measure 1] AS
IIF([Level].[Level].CurrentMember IS [Level].[Level].[Level].[FirstSet],
[Measures].[x],
IIF([Level].[Level].CurrentMember IS [Level].[Level].[Level].[SecondSet],
[Measures].[y],
[Measures].[z]
)
)
现在尝试应用Mosha的模式(我以前没有尝试过,所以您需要进行相应的调整)
您是否可以使用
IS
运算符替换这些语句,例如[Level].[Level].[Level].[Level].[CurrentMember.Member_Key='FirstSet'
用于特定成员,例如[Level].[Level].[Level].[FirstSet].[code>这些空语句的目的是什么?成员[Level].[Level1].[FirstSet]AS NULL
我尝试用IS运算符替换,但不起作用。NULL成员的目的只是为[Common CrossJoin set](或[Level].[Level2].成员)中的每个成员创建一个空行,其中包含特定的集合。为什么不起作用?
是检查成员之间平等性的标准方法,速度会更快:是的,我知道。可能是因为本例中的成员为空,这就是为什么我通过名称设置的成员密钥进行比较。无论如何,此算法的比较部分不是瓶颈。总执行时间大约需要60-100毫秒离子时间,但它只是百分之几。您认为,也许还有其他方法可以从根本上重写查询?您能否替换这些语句[Level].[Level].[Level]。CurrentMember.Member\u Key='FirstSet'
用于使用is
运算符的特定成员,例如[Level].[Level]。CurrentMember是[Level].[Level].[Level]。[FirstSet]
这些NULL语句的用途是什么?成员[Level].[Level 1].[FirstSet]为NULL
我尝试用is运算符替换,但无效。NULL成员的用途只是为[Common CrossJoin set](或[Level].[Level 2].成员)中的每个成员创建一个空行,其中包含特定的集合。为什么不起作用?是检查成员之间平等性的标准方法,速度会更快:是的,我知道。可能是因为本例中的成员为空,这就是为什么我通过名称设置的成员密钥进行比较。无论如何,此算法的比较部分不是瓶颈。总执行时间大约需要60-100毫秒离子时间,但它只是百分之几。你认为,也许还有其他方法可以从根本上重写查询?嗨,whytheq,谢谢你的回答。我理解这个解决方案的想法,并在我的查询中实现了它,所以结果是一样的,但到目前为止性能没有任何改善。甚至计算出的单元格数也是一样的在MdxStudio中几乎相同。您好,whytheq,谢谢您的回答。我理解了此解决方案的思想,并在查询中实现了它,因此结果相同,但到目前为止性能没有任何改进。甚至在MdxStudio中计算的单元格数也几乎相同。