Forum Discussion

Anonymous's avatar
Anonymous
Not applicable
7 years ago
Solved

Performance : calculating Moving average

Hi Everyone,   I am facing some performance issues when i try to calculate moving average on data. I do not have time dimension but i have some indexes that represent time (1,2,3,...) and some valu...
  • Anonymous's avatar
    Anonymous
    7 years ago

    Anonymous -

    The query is slow because there are no grouping indexes. Without index(es) to group the rows, it will iterate the entire table for each row.

     

    The solution that I tried earlier didn't group them into big enough groups. You will need to optimize the exact number and size of grouping, but the concept is this:

     

    //Create the Table
    Moving Average DAX = 
    ADDCOLUMNS(
        GENERATESERIES(1,20000,1), 
        "MyValue",
        CEILING(RAND()*100,1)
    )
    
    //Rename the first column idx, for clarity
    
    //Calculated Columns:
    //This consists of a pair of groups at each level, to cover forward and backward. You can adjust the number and size of groups, but the smallest group needs to cover the necessary range.
    GroupLarge1 = rounddown(DIVIDE('Moving Average DAX'[idx], 500),0)
    GroupLarge2 = rounddown(DIVIDE('Moving Average DAX'[idx] + 250, 500),0)
    
    GroupSmall1 = rounddown(DIVIDE('Moving Average DAX'[idx], 20),0)
    GroupSmall2 = rounddown(DIVIDE('Moving Average DAX'[idx] + 10, 20),0)
    
    //Measure:
    //
    Moving Average = 
    var cur_idx = MAX('Moving Average DAX'[idx])
    var cur_grp1 = MAX('Moving Average DAX'[GroupSmall1])
    var cur_grp2 = MAX('Moving Average DAX'[GroupSmall2])
    var mytablarge = DISTINCT(
        UNION(
            ALLEXCEPT('Moving Average DAX', 'Moving Average DAX'[GroupLarge1]), 
            ALLEXCEPT('Moving Average DAX', 'Moving Average DAX'[GroupLarge2])
        )
    )
    //If you want to add more grouping levels, you'll need to create a pair of variables for each level and create a table variable for each level
    var mytabsmall = DISTINCT(
        UNION(
            FILTER(mytablarge, [GroupSmall1] = cur_grp1), 
            FILTER(mytablarge, [GroupSmall2] = cur_grp2)
        )
    )
    return AVERAGEX( 
        FILTER(
            mytabsmall,
            AND([idx] -10<= cur_idx , [idx] +10>= cur_idx)
        ),
        [MyValue]
    )