【问题标题】:MDX Query using Aggregate Filter Calculated Member too slow使用聚合过滤器计算成员的 MDX 查询太慢
【发布时间】:2016-10-28 09:37:33
【问题描述】:

我是 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]
);

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

非常感谢

【问题讨论】:

    标签: reporting-services filter aggregate mdx


    【解决方案1】:

    CASE 和 FILTER 都是慢速 mdx 函数。对于微不足道的CASE,切换到通常性能更好的IIF 很容易——但是你有太多条件可以嵌套IIFs。

    可能有帮助的三点:

    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]
    );
    

    【讨论】:

    • @user2463061 我发现了另一个严重的问题 - 您应该始终在 WITH 子句中将成员按正确的运行顺序排列。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-06-24
    • 2019-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多