MDX - 非交叉的大交叉连接 - 如何优化性能

时间:2014-08-29 12:26:05

标签: performance mdx iccube

我在总帐管理系统代码块的基础上在icCube中构建了一个模型,该代码块具有以下维度(非限制性):

  • 时间
  • 实体
  • 成本中心
  • 帐户
  • 公司间派对
  • 项目
  • 活动
  • 金额(这是值)

在工具Planning中加载此模型时,如果x轴上的3个以上维度折叠到底层,则会出现性能问题。

我试图检查icCube是否可以更好地处理这个问题,但是3维的语句花了我超过1700秒:

select [Dec] on 0
, non empty { Descendants([Account].[Account].[Total],,leaves) }
     * { Descendants([Activity].[Activity].[Total],,leaves) }
     * { Descendants([CostCenter].[CostCenter].[Total],,leaves) } on 1
from finance

在行上有多个维度的原因是用户希望尽可能多地查看代码块的详细信息,最好是完整的代码块。

我受到以下事实的挑战:其他工具可以非常轻松地处理这类事情,因为它没有OLAP数据库底层,但它使用层次结构直接在数据单元上查询。在Excel中查询数据的提取时获得相同的性能(没有太多的数据行)。

有关数据的信息:

  • 维度非常巨大:400个帐户,6000多个活动,50个实体,50​​0个CostCenters
  • 尺寸活动和项目非常平坦(几乎没有结构)
  • 只有50.000金额,因此数据非常稀少

有任何建议或暗示如何解决这个问题?

1 个答案:

答案 0 :(得分:4)

这是MDX中的经典问题,值得创建MDX反模式并将其作为数字1。

您正在计算的交叉连接将产生400x60000x500 = 12000000000(12X10 ^ 9)元组,我们要求评估它们中的每一个。这使得每秒进行大量评估。

看起来像进行钻取的“奇怪”方式。我会去drillthrough,但让我们尝试在MDX中解决这个问题:

该解决方案正在尝试尽快减少通过执行nonempty生成的元组数量。所以:

 noempty( noempty(A) x noempty(B) ) x noempty(C)
   or 
 noempty(A) x noempty( noempty(B)  x noempty(C) )

使用少数非空的第一个版本:

select 
[Dec] on 0, 
nonempty( 
  nonempty( 
      Descendants([Account].[Account].[Total],,leaves)
    * nonempty( Descendants([Activity].[Activity].[Total],,leaves) , [DEC] )
  , [DEC] )
  * { Descendants([CostCenter].[CostCenter].[Total],,leaves) } 
, [DEC] )
on 1
from [finance]

在icCube中,您将创建一个Function来执行此操作以简化语法:

 Function megaCrossjoin1(A,B,C,M) as nonempty( nonempty(A,M) * nonempty(B,M), M) * nonempty(C,M)

并使用它

megaCrossjoin1( 
   Descendants([Account].[Account].[Total],,leaves) ,
   Descendants([Activity].[Activity].[Total],,leaves) ,
   Descendants([CostCenter].[CostCenter].[Total],,leaves) ,
   [Dec]) 

希望有所帮助