【发布时间】:2016-11-03 12:34:42
【问题描述】:
我有一个很长的复杂查询,其中包含很多计算和条件,但主要结构如下所示:
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.SecondSet成员║L2-3║L1-98║3║7║
║L2成员║L1.SecondSet成员║L2-4║L1-99║4║8║
结果正确,但查询速度很慢(>4 秒)。我的实际查询更大,并且包含很多这样的集合和度量,所以看起来问题出在现有功能和整体结构中,阻止了引擎执行内部优化。
这种方案是错误的,丑陋的,但我怎样才能重写它并更快地得到相同的结果呢?
【问题讨论】:
-
您能否使用
IS运算符替换这些语句[Level].[Level].CurrentMember.Member_Key = 'FirstSet'用于确定的成员,例如[Level].[Level].CurrentMember IS [Level].[Level].[Level].[FirstSet] -
这些 NULL 语句的目的是什么?
MEMBER [Level].[Level1].[FirstSet] AS NULL -
我尝试用 IS 运算符替换,但它不起作用。 NULL成员的目的只是为[Common CrossJoin Set](或[Level].[Level2].Members)中的每个成员创建一个包含特定集合的空行。
-
为什么它不起作用 -
IS是检查成员之间相等性的标准方法,并且会更快:msdn.microsoft.com/en-us/library/ms145997.aspx -
是的,我知道。也许是因为在这种情况下 member 为 NULL,这就是为什么我通过 name 设置的 member_key 来比较它。无论如何,该算法的比较部分不是瓶颈。总执行时间大约需要 60-100 毫秒,但只有百分之几。您怎么看,也许还有其他方法可以从根本上重写查询?
标签: ssas mdx olap query-performance mdxstudio