简体   繁体   中英

Slow SSAS cumulative sum calculated measure

I have a cumulative sum of a measure structured as:

Aggregate (
    { NULL : [Date].[Year - Month - Date].CurrentMember } 
    ,[Measures].[Applications] )

From the date of the first application to the current date, the days of the date range must be contiguous.

The Date dimension however contains dates ranging from 1900-01-01 to well into the future.

I've attempted to eliminate dates before the first application, and future dates by structuring the calculated measure as follows:

CREATE MEMBER CURRENTCUBE.[Measures].[Applications TD] AS
CASE 
WHEN   
    /* Eliminates dates before first applications, i.e. year 1900-01-01 */
    Aggregate (
        { NULL : [Date].[Year - Month - Date].CurrentMember } 
        ,[Measures].[Applications] ) < 0   
THEN NULL
WHEN
    /* Eliminates dates after today */
    [Date].[Year - Month - Date].CurrentMember.MemberValue >= StrToMember('[Date].[Date].&['+Format(Now(),"yyyy-MM-ddT00:00:00")+']').MemberValue 
THEN NULL
ELSE
    Aggregate (
            { NULL : [Date].[Year - Month - Date].CurrentMember } 
            ,[Measures].[Applications] )           
END

I have been unsuccessful in any attempt to optimizing this by aggregating only where needed using a SCOPE as an alternative to the case statement, utilizing EXISTS and EXCEPT functions and many others.

When browsing the cube and dimensioning [Measures].[Applications TD] by [Date].[Year - Month - Date] user-defined hierarchy it is terribly slow.

IIF is generally faster than CASE , and SUM is often faster than AGGREGATE .
Although your main problem is the second part of your condition using membervalue - is it required or will the following not do the same thing? :

CREATE MEMBER CURRENTCUBE.[Measures].[Applications TD] AS
IIF(
     SUM (
        { NULL : [Date].[Year - Month - Date].CurrentMember } 
        ,[Measures].[Applications] 
     ) < 0 
   , NULL
   , 
   SUM (
         { NULL : [Date].[Year - Month - Date].CurrentMember } 
          ,[Measures].[Applications] 
    ) 
)

I'd separate this out as a custom member:

CREATE MEMBER CURRENTCUBE.[Date].[Date].[All].[Today] AS //<< a  little of syntax for this create 
    StrToMember('[Date].[Date].&['+Format(Now(),"yyyy-MM-ddT00:00:00")+']')

Then try a nested IIF :

CREATE MEMBER CURRENTCUBE.[Measures].[Applications TD] AS
IIF(
    [Date].[Year - Month - Date].CurrentMember.MemberValue >= [Date].[Date].[All].[Today].MemberValue
   , NULL
   , IIF(
       SUM (
          { NULL : [Date].[Year - Month - Date].CurrentMember } 
          ,[Measures].[Applications] 
       ) < 0 
     , NULL
     , 
     SUM (
           { NULL : [Date].[Year - Month - Date].CurrentMember } 
            ,[Measures].[Applications] 
      ) 
  )
)

BUT

Rather than bothering with the "Today" member it will be a lot more efficient if you add an isToday column to DimDate - then have an attribute of the cubes date dimension using the column. That way you should be able to simplify this [Date].[Year - Month - Date].CurrentMember.MemberValue >= [Date].[Date].[All].[Today].MemberValue

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM