这个MDX可以优化吗?

时间:2015-03-31 12:34:36

标签: mdx

我有一个MDX查询如下:

WITH
MEMBER [Measures].[Percentage of All Accounts] AS [Measures].[SUM Principal EUR]/SUM({[Contract].[Product Group].&[P1], [Contract].[Product Group].&[P2], [Contract].[Product Group].&[P3]}, [Measures].[SUM Principal EUR])
SELECT
    NON EMPTY
    {
        [Measures].[SUM Principal EUR],
        [Measures].[SUM Principal USD],
        [Measures].[SUM Principal Local Currency],
        [Measures].[Percentage of All Accounts]
    } ON COLUMNS,
    NON EMPTY
    { (
        [Contract].[Product Group].ALLMEMBERS,
        [Dates].[YearMonth].ALLMEMBERS
    ) } ON ROWS
FROM 
(
    SELECT
    { (
        STRTOSET(@ContractProductGroup, CONSTRAINED),
        STRTOSET(@DatesYearMonth, CONSTRAINED)
    ) } ON 0
    FROM [Assets]
)
WHERE
{
    { [Contract].[Unit].&[U1], [Contract].[Unit].&[U2], [Contract].[Unit].&[U3] },
    [Assets Cont].[Contract Status].&[C1]
}

这可以优化吗?

我知道你不能在你的机器上运行它,但我想知道这个查询中有什么不是一个好的做法,或者它可以做得更好。

2 个答案:

答案 0 :(得分:1)

您可以通过引入一些空值来使您的自定义度量更加稀疏 同样在ON ROWS上,为什么不使用正常的交叉连接 试试.MEMBERS而不是.ALLMEMBERS功能 您可以尝试在WITH子句中创建自定义集:[nonEmpSet] 此外,我已将WHERE子句中的花括号更改为元组括号,因为这更为标准。

WITH 
  SET [nonEmpSet] AS 
    NonEmpty
    (
      {
        [Contract].[Product Group].MEMBERS * [Dates].[YearMonth].MEMBERS
      },
     ,[Measures].[SUM Principal EUR]
    ) 
  MEMBER [Measures].[Accounts NEW] AS 
    Aggregate
    (
      {
        [Contract].[Product Group].&[P1]
       ,[Contract].[Product Group].&[P2]
       ,[Contract].[Product Group].&[P3]
      }
     ,[Measures].[SUM Principal EUR]
    ) 
  MEMBER [Measures].[Percentage of All Accounts] AS 
    IIF
    (
      [Measures].[Accounts NEW] = 0
     ,null
     ,
      [Measures].[SUM Principal EUR] / [Measures].[Accounts NEW]
    ) 
SELECT 
  NON EMPTY 
    {
      [Measures].[SUM Principal EUR]
     ,[Measures].[SUM Principal USD]
     ,[Measures].[SUM Principal Local Currency]
     ,[Measures].[Percentage of All Accounts]
    } ON COLUMNS
 ,NON EMPTY 
    [nonEmpSet] ON ROWS
FROM 
(
  SELECT 
    {
      (
        StrToSet
        (@ContractProductGroup
         ,CONSTRAINED
        )
       ,StrToSet
        (@DatesYearMonth
         ,CONSTRAINED
        )
      )
    } ON 0
  FROM [Assets]
)
WHERE 
  (
    {
      [Contract].[Unit].&[U1]
     ,[Contract].[Unit].&[U2]
     ,[Contract].[Unit].&[U3]
    }
   ,[Assets Cont].[Contract Status].&[C1]
  );

答案 1 :(得分:0)

如果不是问题,请创建一个多维数据集级别的成员,如下所示:

CREATE
MEMBER [Measures].[Percentage of All Accounts] AS NULL;

SCOPE(
{
    { [Contract].[Unit].&[U1], [Contract].[Unit].&[U2], [Contract].[Unit].&[U3] },
    [Assets Cont].[Contract Status].&[C1]
});

[Measures].[Percentage of All Accounts] =
Measures].[SUM Principal EUR]
/
SUM({[Contract].[Product Group].&[P1], [Contract].[Product Group].&[P2], [Contract].[Product Group].&[P3]}, [Measures].[SUM Principal EUR]);

END SCOPE;

同样在您的查询中使用NonEmpty()函数来摆脱不必要的交叉连接。

SELECT
    NON EMPTY
    {
        [Measures].[SUM Principal EUR],
        [Measures].[SUM Principal USD],
        [Measures].[SUM Principal Local Currency],
        [Measures].[Percentage of All Accounts]
    } ON COLUMNS,
    NON EMPTY 
    NonEmpty(
        [Contract].[Product Group].ALLMEMBERS,
        [Dates].[YearMonth].ALLMEMBERS
    ) ON ROWS
FROM 
(
    SELECT
    { (
        STRTOSET(@ContractProductGroup, CONSTRAINED),
        STRTOSET(@DatesYearMonth, CONSTRAINED)
    ) } ON 0
    FROM [Assets]
)

编辑 - WHERE子句而不是子选择

WITH MEMBER [Measures].[Percentage of All Accounts] AS 
[Measures].[SUM Principal EUR]
/
SUM({[Contract].[Product Group].&[P1], [Contract].[Product Group].&[P2], [Contract].[Product Group].&[P3]}, [Measures].[SUM Principal EUR])

SELECT
    NON EMPTY
    {
        [Measures].[SUM Principal EUR],
        [Measures].[SUM Principal USD],
        [Measures].[SUM Principal Local Currency],
        [Measures].[Percentage of All Accounts]
    } ON COLUMNS,
    NON EMPTY
    { (
        [Contract].[Product Group].ALLMEMBERS,
        [Dates].[YearMonth].ALLMEMBERS
    ) } ON ROWS

    FROM [Assets]
WHERE
{
    { [Contract].[Unit].&[U1], [Contract].[Unit].&[U2], [Contract].[Unit].&[U3] },
    [Assets Cont].[Contract Status].&[C1],
    STRTOSET(@ContractProductGroup, CONSTRAINED),
    STRTOSET(@DatesYearMonth, CONSTRAINED)
}

编辑2

WITH MEMBER [Measures].[Percentage of All Accounts] AS 
[Measures].[SUM Principal EUR]
/
SUM({[Contract].[Product Group].&[P1], [Contract].[Product Group].&[P2], [Contract].[Product Group].&[P3]}, [Measures].[SUM Principal EUR])

SELECT
    NON EMPTY
    {
        [Measures].[SUM Principal EUR],
        [Measures].[SUM Principal USD],
        [Measures].[SUM Principal Local Currency],
        [Measures].[Percentage of All Accounts]
    } ON COLUMNS,
    NON EMPTY
    { (
       STRTOSET(@ContractProductGroup, CONSTRAINED),
       STRTOSET(@DatesYearMonth, CONSTRAINED)
    ) } ON ROWS

    FROM [Assets]
WHERE
{
    { [Contract].[Unit].&[U1], [Contract].[Unit].&[U2], [Contract].[Unit].&[U3] },
    [Assets Cont].[Contract Status].&[C1]
}