MDX效率,来自同一层次结构的度量

时间:2016-02-07 19:32:07

标签: vba excel-vba ssas mdx excel

VBA / SQL我相当高级。

我正在使用Excel中SSAS多维数据集的摘录来替换数据透视表。我无法访问SQL serverSSMS。我第一次使用MDX直接从多维数据集中提取此信息。

这样做的主要原因是删除手动多维数据集数据透视表更新,其中发生了问题,个人对数据透视表进行了压缩和/或未向下扩展其他公式以匹配它。

我已经制作了一个适合我的查询,它在下面提供(加载到strMdx中的VBA字符串中):

    strMDX = "WITH MEMBER [Measures].[Sector] as ANCESTOR([Sector].[IndH].CURRENTMEMBER,[Sector].[IndH].[Sector]).NAME "
    strMDX = strMDX & "MEMBER [Measures].[Industry] as ANCESTOR([Sector].[IndH].CURRENTMEMBER,[Sector].[IndH].[Industry]).NAME "
    strMDX = strMDX & "MEMBER [Measures].[Sub Industry] as ANCESTOR([Sector].[IndH].CURRENTMEMBER,[Sector].[IndH].[Sub Industry]).NAME "
    strMDX = strMDX & "MEMBER [Measures].[Account] as ANCESTOR([Sector].[IndH].CURRENTMEMBER,[Sector].[IndH].[Account]).NAME "
    strMDX = strMDX & "MEMBER [Measures].[Sub Account] as ANCESTOR([Sector].[IndH].CURRENTMEMBER,[Sector].[IndH].[Sub Account]).NAME "
    strMDX = strMDX & "MEMBER [Measures].[Level] as ANCESTOR([Sector].[IndH].CURRENTMEMBER,[Sector].[IndH].[Level]).NAME "
    strMDX = strMDX & "SELECT NON EMPTY ( {[Measures].[Sector], [Measures].[Industry], [Measures].[Sub Industry], [Measures].[Account], [Measures].[Sub Account], [Measures].[Level], "
    strMDX = strMDX & "[Measures].[iCounts] }) ON 0, "
    strMDX = strMDX & "NON EMPTY( [Date].[DayYear].[Year],[Date].[MonthYear].[MonthName]) ON 1, "
    strMDX = strMDX & "NON EMPTY( DESCENDANTS([Sector].[IndH],,LEAVES)) HAVING [Measures].[iCounts] >0 ON 2 FROM ( SELECT ( "
    strMDX = strMDX & "[Date].[MonthYear].[Date].&[" & Format(strStartDte, "yyyymmdd") & "]&[" & Format(strStartDte, "dd mmm yyyy") & "] : "
    strMDX = strMDX & "[Date].[MonthYear].[Date].&[" & Format(strEndDte, "yyyymmdd") & "]&[" & Format(strEndDte, "dd mmm yyyy") & "] ) "
    strMDX = strMDX & "ON 0 FROM [IndustryCube])"

这是MDX

WITH 
MEMBER [MeASures].[Sector] AS 
    ANCESTOR([Sector].[IndH].CURRENTMEMBER,[Sector].[IndH].[Sector]).NAME 
MEMBER [MeASures].[Industry] AS 
    ANCESTOR([Sector].[IndH].CURRENTMEMBER,[Sector].[IndH].[Industry]).NAME 
MEMBER [MeASures].[Sub Industry] AS 
    ANCESTOR([Sector].[IndH].CURRENTMEMBER,[Sector].[IndH].[Sub Industry]).NAME 
MEMBER [MeASures].[Account] AS 
    ANCESTOR([Sector].[IndH].CURRENTMEMBER,[Sector].[IndH].[Account]).NAME 
MEMBER [MeASures].[Sub Account] AS 
    ANCESTOR([Sector].[IndH].CURRENTMEMBER,[Sector].[IndH].[Sub Account]).NAME 
MEMBER [MeASures].[Level] AS 
    ANCESTOR([Sector].[IndH].CURRENTMEMBER,[Sector].[IndH].[Level]).NAME 
SELECT 
NON EMPTY 
( 
    { [MeASures].[Sector]
    , [MeASures].[Industry]
    , [MeASures].[Sub Industry]
    , [MeASures].[Account]
    , [MeASures].[Sub Account]
    , [MeASures].[Level], 
      [MeASures].[iCounts] }
) ON 0, 
NON EMPTY 
    (
     [Date].[DayYear].[Year]
    ,[Date].[MonthYear].[MonthName]) ON 1, 
NON EMPTY
    (DESCENDANTS([Sector].[IndH],,LEAVES)) 
HAVING [MeASures].[iCounts] > 0 ON 2 
FROM ( 
    SELECT ( 
        [Date].[MonthYear].[Date].&[ & Format(strStartDte, yyyymmdd) ]&[ & Format(strStartDte, dd mmm yyyy) ] : 
        [Date].[MonthYear].[Date].&[ & Format(strEndDte, yyyymmdd) ]&[ & Format(strEndDte, dd mmm yyyy) ] ) 
        ON 0 
    FROM [IndustryCube]
)

此查询有两个关键方面需要注意:

  1. 这是一个3轴查询 - 在我之后使用VBA中的循环编写它时非常适合。
  2. 我需要拆分并使用同一层次结构中的多个级别([Sector].[IndH]),因此我需要展平层次结构。我使用后代然后通过将每个级别定义为它自己的度量来完成此操作。这确实可以平衡层次结构,但我认为这是一种解决方法。
  3. 除了上述两点之外,我认为它是一个非常标准的MDX声明。

    我遇到的关键问题是,如果我运行一个月或两个月,查询运行得非常好,尽管只需要一分钟。如果我运行它超过5年(我需要),那么它需要大量的时间,我从来没有让它成功运行。

    我是否可以对此查询做些什么来从性能角度对其进行改进?

    我怀疑这个问题与扁平化层次结构有关。不幸的是,没有办法解决这个问题,因为多维数据集尚未在层次结构之外设置单独的维度,或者包含我需要的字段的另一个层次结构。

1 个答案:

答案 0 :(得分:1)

我很想将它移到mdx内的几个vba脚本中,试图让事情比其他任何事情更具可读性。

我猜测在vba你循环通过第三轴的成员。如果是这样,请从您的大脚本中取出并创建一个返回这些成员的小型mdx脚本。也许像:

SELECT 
NON EMPTY 
    [MeASures].[iCounts] ON 0,  
NON EMPTY
    DESCENDANTS([Sector].[IndH],,LEAVES)  ON 1 
FROM ( 
    SELECT ( 
        [Date].[MonthYear].[Date].&[ & Format(strStartDte, yyyymmdd) ]&[ & Format(strStartDte, dd mmm yyyy) ] : 
        [Date].[MonthYear].[Date].&[ & Format(strEndDte, yyyymmdd) ]&[ & Format(strEndDte, dd mmm yyyy) ] ) 
        ON 0 
    FROM [IndustryCube]
)

外部循环可以迭代从上面返回的成员,并将每个成员提供给以下内容:

SELECT 
NON EMPTY 
    [MeASures].[iCounts]  ON 0, 
NON EMPTY 
    [Date].[DayYear].[Year]
    *[Date].[MonthYear].[MonthName]
    *[Sector].[IndH].[Sector]
    *[Sector].[IndH].[Industry]
    *[Sector].[IndH].[Sub Industry]
    *[Sector].[IndH].[Account]
    *[Sector].[IndH].[Sub Account]
    *[Sector].[IndH].[Level] ON 1 
FROM 
( 
    SELECT  
        [Date].[MonthYear].[Date].&[ & Format(strStartDte, yyyymmdd) ]&[ & Format(strStartDte, dd mmm yyyy) ] : 
        [Date].[MonthYear].[Date].&[ & Format(strEndDte, yyyymmdd) ]&[ & Format(strEndDte, dd mmm yyyy) ]  
        ON 0, 
        [Sector].[IndH].&[ ....strFromOuterLoopHere...  ON 1
    FROM [IndustryCube]
);

使用mdx时要注意的一件事是大括号(..) - 这向处理器表明你想创建一个元组;你问题中的脚本有很多额外的括号。