使用聚合筛选计算成员的MDX查询太慢

时间:2016-10-28 09:37:34

标签: reporting-services filter aggregate mdx

我是MDX的新手。我试图在SSRS报告中运行以下MDX查询,并且需要很长时间才能完成运行它。有时我必须取消查询,因为它太慢了。

WITH 
  --All forms ordered ASC
  SET [OrderedSet] AS 
    Order
    (
      NonEmpty
      (
        [Form].[Number].[Number]
       ,[Measures].[Sales]
      )
     ,[Measures].[Sales]
     ,BASC
    ) 
  --Rank the forms in [orderedSet]
  MEMBER [Measures].[Rank] AS 
    Rank
    (
      [Form].[Number].CurrentMember
     ,[OrderedSet]
    ) 
  --Running Total
  MEMBER [Measures].[Running Total] AS 
    Sum
    (
      Head
      (
        [OrderedSet]
       ,(
          [Measures].[Rank]
         ,[Form].[Number].CurrentMember
        )
      )
     ,[Measures].[Sales]
    ) 
  --Total Sales
  MEMBER [Measures].[Total Sales] AS 
    Sum
    (
      [OrderedSet]
     ,[Measures].[Sales]
    ) 
  --Find the spending band Sales limits
  MEMBER [Measures].[3%Sales] AS 
    0.03 * [Measures].[Total Sales] 
  MEMBER [Measures].[8%Sales] AS 
    0.08 * [Measures].[Total Sales] 
  MEMBER [Measures].[18%Sales] AS 
    0.18 * [Measures].[Total Sales] 
  MEMBER [Measures].[38%Sales] AS 
    0.38 * [Measures].[Total Sales] 
  MEMBER [Measures].[62%Sales] AS 
    0.62 * [Measures].[Total Sales] 
  MEMBER [Measures].[82%Sales] AS 
    0.82 * [Measures].[Total Sales] 
  MEMBER [Measures].[92%Sales] AS 
    0.92 * [Measures].[Total Sales] 
  MEMBER [Measures].[97%Sales] AS 
    0.97 * [Measures].[Total Sales] 
  --Assign Sales limits for each spending bands
  MEMBER [Measures].[MinSales] AS 
    CASE 
      WHEN 
        [Form].[Number].CurrentMember = [Form].[Number].[0-3] 
      THEN 1
      WHEN 
        [Form].[Number].CurrentMember = [Form].[Number].[3-8] 
      THEN 
        [Measures].[3%Sales]
      WHEN 
        [Form].[Number].CurrentMember = [Form].[Number].[8-18] 
      THEN 
        [Measures].[8%Sales]
      WHEN 
        [Form].[Number].CurrentMember = [Form].[Number].[18-38] 
      THEN 
        [Measures].[18%Sales]
      WHEN 
        [Form].[Number].CurrentMember = [Form].[Number].[38-62] 
      THEN 
        [Measures].[38%Sales]
      WHEN 
        [Form].[Number].CurrentMember = [Form].[Number].[62-82] 
      THEN 
        [Measures].[62%Sales]
      WHEN 
        [Form].[Number].CurrentMember = [Form].[Number].[82-92] 
      THEN 
        [Measures].[82%Sales]
      WHEN 
        [Form].[Number].CurrentMember = [Form].[Number].[92-97] 
      THEN 
        [Measures].[92%Sales]
      WHEN 
        [Form].[Number].CurrentMember = [Form].[Number].[97-100] 
      THEN 
        [Measures].[97%Sales]
    END 
  MEMBER [Measures].[MaxSales] AS 
    CASE 
      WHEN 
        [Form].[Number].CurrentMember = [Form].[Number].[0-3] 
      THEN 
        [Measures].[3%Sales]
      WHEN 
        [Form].[Number].CurrentMember = [Form].[Number].[3-8] 
      THEN 
        [Measures].[8%Sales]
      WHEN 
        [Form].[Number].CurrentMember = [Form].[Number].[8-18] 
      THEN 
        [Measures].[18%Sales]
      WHEN 
        [Form].[Number].CurrentMember = [Form].[Number].[18-38] 
      THEN 
        [Measures].[38%Sales]
      WHEN 
        [Form].[Number].CurrentMember = [Form].[Number].[38-62] 
      THEN 
        [Measures].[62%Sales]
      WHEN 
        [Form].[Number].CurrentMember = [Form].[Number].[62-82] 
      THEN 
        [Measures].[82%Sales]
      WHEN 
        [Form].[Number].CurrentMember = [Form].[Number].[82-92] 
      THEN 
        [Measures].[92%Sales]
      WHEN 
        [Form].[Number].CurrentMember = [Form].[Number].[92-97] 
      THEN 
        [Measures].[97%Sales]
      WHEN 
        [Form].[Number].CurrentMember = [Form].[Number].[97-100] 
      THEN 
        [Measures].[Total Sales]
    END 
  --Create Spending bands based on the Running Total ranges
  MEMBER [Form].[Number].[0-3] AS 
    Aggregate
    (
      Filter
      (
        [OrderedSet]
       ,
          [Measures].[Running Total] > 0
        AND 
          [Measures].[Running Total] <= [Measures].[3%Sales]
      )
    ) 
  MEMBER [Form].[Number].[3-8] AS 
    Aggregate
    (
      Filter
      (
        [OrderedSet]
       ,
          [Measures].[Running Total] > [Measures].[3%Sales]
        AND 
          [Measures].[Running Total] <= [Measures].[8%Sales]
      )
    ) 
  MEMBER [Form].[Number].[8-18] AS 
    Aggregate
    (
      Filter
      (
        [OrderedSet]
       ,
          [Measures].[Running Total] > [Measures].[8%Sales]
        AND 
          [Measures].[Running Total] <= [Measures].[18%Sales]
      )
    ) 
  MEMBER [Form].[Number].[18-38] AS 
    Aggregate
    (
      Filter
      (
        [OrderedSet]
       ,
          [Measures].[Running Total] > [Measures].[18%Sales]
        AND 
          [Measures].[Running Total] <= [Measures].[38%Sales]
      )
    ) 
  MEMBER [Form].[Number].[38-62] AS 
    Aggregate
    (
      Filter
      (
        [OrderedSet]
       ,
          [Measures].[Running Total] > [Measures].[38%Sales]
        AND 
          [Measures].[Running Total] <= [Measures].[62%Sales]
      )
    ) 
  MEMBER [Form].[Number].[62-82] AS 
    Aggregate
    (
      Filter
      (
        [OrderedSet]
       ,
          [Measures].[Running Total] > [Measures].[62%Sales]
        AND 
          [Measures].[Running Total] <= [Measures].[82%Sales]
      )
    ) 
  MEMBER [Form].[Number].[82-92] AS 
    Aggregate
    (
      Filter
      (
        [OrderedSet]
       ,
          [Measures].[Running Total] > [Measures].[82%Sales]
        AND 
          [Measures].[Running Total] <= [Measures].[92%Sales]
      )
    ) 
  MEMBER [Form].[Number].[92-97] AS 
    Aggregate
    (
      Filter
      (
        [OrderedSet]
       ,
          [Measures].[Running Total] > [Measures].[92%Sales]
        AND 
          [Measures].[Running Total] <= [Measures].[97%Sales]
      )
    ) 
  MEMBER [Form].[Number].[97-100] AS 
    Aggregate
    (
      Filter
      (
        [OrderedSet]
       ,
          [Measures].[Running Total] > [Measures].[97%Sales]
        AND 
          [Measures].[Running Total] <= [Measures].[Total Sales]
      )
    ) 
SELECT 
  NON EMPTY 
    {
      [Measures].[MinSales]
     ,[Measures].[MaxSales]
     ,[Measures].[Form Count]
     ,[Measures].[Sales]
    } ON 0
 ,{
    [Form].[Number].[0-3]
   ,[Form].[Number].[3-8]
   ,[Form].[Number].[8-18]
   ,[Form].[Number].[18-38]
   ,[Form].[Number].[38-62]
   ,[Form].[Number].[62-82]
   ,[Form].[Number].[82-92]
   ,[Form].[Number].[92-97]
   ,[Form].[Number].[97-100]
  } ON 1
FROM 
(
  SELECT 
    [blah] ON COLUMNS
  FROM [Cube]
);

经过几次测试和谷歌搜索后,我知道罪魁祸首是聚合过滤后的表格编号的计算成员。此外,[表格]。[数字]。[数字]维度是一个巨大的维度,拥有数十万成员。因此,我们想知道如果我们在这样的维度中创建一个计算成员,是否会减慢查询速度,如果是这样,那么解决方法是什么?

非常感谢

1 个答案:

答案 0 :(得分:0)

CASEFILTER都是慢速mdx函数。对于一个微不足道的CASE,切换到通常表现更好的IIF是很容易的 - 但是您有太多条件来嵌套IIF

可能会有所帮助的三点:

1.我注意到您的案例陈述中有错误 - 您应该使用IS运算符而不是=

CASE 
  WHEN 
    [Form].[Number].CurrentMember IS [Form].[Number].[0-3] 
  THEN 1
  WHEN 
    [Form].[Number].CurrentMember IS [Form].[Number].[3-8] 
  THEN 
    [Measures].[3%Sales]
  WHEN 
    [Form].[Number].CurrentMember IS [Form].[Number].[8-18] 
  THEN 
    [Measures].[8%Sales]
  WHEN 
    [Form].[Number].CurrentMember IS [Form].[Number].[18-38] 
  THEN 
    [Measures].[18%Sales]
  WHEN 
    [Form].[Number].CurrentMember IS [Form].[Number].[38-62] 
  THEN 
    [Measures].[38%Sales]
  WHEN 
    [Form].[Number].CurrentMember IS [Form].[Number].[62-82] 
  THEN 
    [Measures].[62%Sales]
  WHEN 
    [Form].[Number].CurrentMember IS [Form].[Number].[82-92] 
  THEN 
    [Measures].[82%Sales]
  WHEN 
    [Form].[Number].CurrentMember IS [Form].[Number].[92-97] 
  THEN 
    [Measures].[92%Sales]
  WHEN 
    [Form].[Number].CurrentMember IS [Form].[Number].[97-100] 
  THEN 
    [Measures].[97%Sales]
END 

2. WITH子句的运行顺序错误 - 这些不同的成员[Form].[Number].[97-100]CASE语句中使用后会计算出来。

3.您对[Total Sales]的计算我无法想象需要任何排序,为什么要使用有序集?事实上,您可以使用层次结构中[All]成员的元组来获取此值:

--Total Sales
MEMBER [Measures].[Total Sales] AS 
(
  [Form].[Number].[All]
 ,[Measures].[Sales]
)

因此,我们现在实现上述目标:

WITH 
  --All forms ordered ASC
  SET [OrderedSet] AS 
    Order
    (
      NonEmpty
      (
        [Form].[Number].[Number]
       ,[Measures].[Sales]
      )
     ,[Measures].[Sales]
     ,BASC
    ) 
  --Rank the forms in [orderedSet]
  MEMBER [Measures].[Rank] AS 
    Rank
    (
      [Form].[Number].CurrentMember
     ,[OrderedSet]
    ) 
  --Running Total
  MEMBER [Measures].[Running Total] AS 
    Sum
    (
      Head
      (
        [OrderedSet]
       ,(
          [Measures].[Rank]
         ,[Form].[Number].CurrentMember
        )
      )
     ,[Measures].[Sales]
    ) 
  --Total Sales
  MEMBER [Measures].[Total Sales] AS 
  (
    [Form].[Number].[All]
   ,[Measures].[Sales]
  )
  --Find the spending band Sales limits
  MEMBER [Measures].[3%Sales] AS 
    0.03 * [Measures].[Total Sales] 
  MEMBER [Measures].[8%Sales] AS 
    0.08 * [Measures].[Total Sales] 
  MEMBER [Measures].[18%Sales] AS 
    0.18 * [Measures].[Total Sales] 
  MEMBER [Measures].[38%Sales] AS 
    0.38 * [Measures].[Total Sales] 
  MEMBER [Measures].[62%Sales] AS 
    0.62 * [Measures].[Total Sales] 
  MEMBER [Measures].[82%Sales] AS 
    0.82 * [Measures].[Total Sales] 
  MEMBER [Measures].[92%Sales] AS 
    0.92 * [Measures].[Total Sales] 
  MEMBER [Measures].[97%Sales] AS 
    0.97 * [Measures].[Total Sales] 
  --Create Spending bands based on the Running Total ranges
  MEMBER [Form].[Number].[0-3] AS 
    Aggregate
    (
      Filter
      (
        [OrderedSet]
       ,
          [Measures].[Running Total] > 0
        AND 
          [Measures].[Running Total] <= [Measures].[3%Sales]
      )
    ) 
  MEMBER [Form].[Number].[3-8] AS 
    Aggregate
    (
      Filter
      (
        [OrderedSet]
       ,
          [Measures].[Running Total] > [Measures].[3%Sales]
        AND 
          [Measures].[Running Total] <= [Measures].[8%Sales]
      )
    ) 
  MEMBER [Form].[Number].[8-18] AS 
    Aggregate
    (
      Filter
      (
        [OrderedSet]
       ,
          [Measures].[Running Total] > [Measures].[8%Sales]
        AND 
          [Measures].[Running Total] <= [Measures].[18%Sales]
      )
    ) 
  MEMBER [Form].[Number].[18-38] AS 
    Aggregate
    (
      Filter
      (
        [OrderedSet]
       ,
          [Measures].[Running Total] > [Measures].[18%Sales]
        AND 
          [Measures].[Running Total] <= [Measures].[38%Sales]
      )
    ) 
  MEMBER [Form].[Number].[38-62] AS 
    Aggregate
    (
      Filter
      (
        [OrderedSet]
       ,
          [Measures].[Running Total] > [Measures].[38%Sales]
        AND 
          [Measures].[Running Total] <= [Measures].[62%Sales]
      )
    ) 
  MEMBER [Form].[Number].[62-82] AS 
    Aggregate
    (
      Filter
      (
        [OrderedSet]
       ,
          [Measures].[Running Total] > [Measures].[62%Sales]
        AND 
          [Measures].[Running Total] <= [Measures].[82%Sales]
      )
    ) 
  MEMBER [Form].[Number].[82-92] AS 
    Aggregate
    (
      Filter
      (
        [OrderedSet]
       ,
          [Measures].[Running Total] > [Measures].[82%Sales]
        AND 
          [Measures].[Running Total] <= [Measures].[92%Sales]
      )
    ) 
  MEMBER [Form].[Number].[92-97] AS 
    Aggregate
    (
      Filter
      (
        [OrderedSet]
       ,
          [Measures].[Running Total] > [Measures].[92%Sales]
        AND 
          [Measures].[Running Total] <= [Measures].[97%Sales]
      )
    ) 
  MEMBER [Form].[Number].[97-100] AS 
    Aggregate
    (
      Filter
      (
        [OrderedSet]
       ,
          [Measures].[Running Total] > [Measures].[97%Sales]
        AND 
          [Measures].[Running Total] <= [Measures].[Total Sales]
      )
    ) 
  --Assign Sales limits for each spending bands
  MEMBER [Measures].[MinSales] AS 
    CASE 
      WHEN 
        [Form].[Number].CurrentMember IS [Form].[Number].[0-3] 
      THEN 1
      WHEN 
        [Form].[Number].CurrentMember IS [Form].[Number].[3-8] 
      THEN 
        [Measures].[3%Sales]
      WHEN 
        [Form].[Number].CurrentMember IS [Form].[Number].[8-18] 
      THEN 
        [Measures].[8%Sales]
      WHEN 
        [Form].[Number].CurrentMember IS [Form].[Number].[18-38] 
      THEN 
        [Measures].[18%Sales]
      WHEN 
        [Form].[Number].CurrentMember IS [Form].[Number].[38-62] 
      THEN 
        [Measures].[38%Sales]
      WHEN 
        [Form].[Number].CurrentMember IS [Form].[Number].[62-82] 
      THEN 
        [Measures].[62%Sales]
      WHEN 
        [Form].[Number].CurrentMember IS [Form].[Number].[82-92] 
      THEN 
        [Measures].[82%Sales]
      WHEN 
        [Form].[Number].CurrentMember IS [Form].[Number].[92-97] 
      THEN 
        [Measures].[92%Sales]
      WHEN 
        [Form].[Number].CurrentMember IS [Form].[Number].[97-100] 
      THEN 
        [Measures].[97%Sales]
    END 
  MEMBER [Measures].[MaxSales] AS 
    CASE 
      WHEN 
        [Form].[Number].CurrentMember IS [Form].[Number].[0-3] 
      THEN 
        [Measures].[3%Sales]
      WHEN 
        [Form].[Number].CurrentMember IS [Form].[Number].[3-8] 
      THEN 
        [Measures].[8%Sales]
      WHEN 
        [Form].[Number].CurrentMember IS [Form].[Number].[8-18] 
      THEN 
        [Measures].[18%Sales]
      WHEN 
        [Form].[Number].CurrentMember IS [Form].[Number].[18-38] 
      THEN 
        [Measures].[38%Sales]
      WHEN 
        [Form].[Number].CurrentMember IS [Form].[Number].[38-62] 
      THEN 
        [Measures].[62%Sales]
      WHEN 
        [Form].[Number].CurrentMember IS [Form].[Number].[62-82] 
      THEN 
        [Measures].[82%Sales]
      WHEN 
        [Form].[Number].CurrentMember IS [Form].[Number].[82-92] 
      THEN 
        [Measures].[92%Sales]
      WHEN 
        [Form].[Number].CurrentMember IS [Form].[Number].[92-97] 
      THEN 
        [Measures].[97%Sales]
      WHEN 
        [Form].[Number].CurrentMember IS [Form].[Number].[97-100] 
      THEN 
        [Measures].[Total Sales]
    END 
SELECT 
  NON EMPTY 
    {
      [Measures].[MinSales]
     ,[Measures].[MaxSales]
     ,[Measures].[Form Count]
     ,[Measures].[Sales]
    } ON 0
 ,{
    [Form].[Number].[0-3]
   ,[Form].[Number].[3-8]
   ,[Form].[Number].[8-18]
   ,[Form].[Number].[18-38]
   ,[Form].[Number].[38-62]
   ,[Form].[Number].[62-82]
   ,[Form].[Number].[82-92]
   ,[Form].[Number].[92-97]
   ,[Form].[Number].[97-100]
  } ON 1
FROM 
(
  SELECT 
    [blah] ON COLUMNS
  FROM [Cube]
);