Optimising DAX Measures

JB2020

Board Regular
Joined
Jul 29, 2020
Messages
88
Office Version
  1. 365
  2. 2016
  3. 2010
Platform
  1. Windows
I'm looking to optimise the following measures with the aim of creating a pivot table containing 'MyValue' and a grand average 2 point moving range centre line (the AverageMovingRange measure below).

Because various other fields can be added as filters, as well as ID being grouped by fields, this means that I can not use a calculated column as it needs to be dynamic. Below is an example of an output I am looking to achieve, where Category and ID are 'Rows' in a pivot table and my measures and the [sum of] MyValues field are 'Values'.

It's also probably worth mentioning that the ID field is unique in each row of the 'Data' table.

1642527911666.png


The two measures below produce the desired output when the table size is small (a few hundred rows). However, with the full table containing tens of thousands of rows it seems to take an eternity, even when filters are applied. Any help on how to optimize these measures is greatly appreciated.
Please let me know if you need me to provide any more info, thanks in advance!

Current Measures:

This measure looks for the next largest ID than the one in the current row context, retrieves the value of the 'MyValue' field for that row, then takes the absolute value of that, minus the current MyValue for that row.
Rich (BB code):
Moving Range = 

VAR RowID = LASTNONBLANK('Data'[ID],1)


VAR LastID = CALCULATE(
    MAX('Data'[ID]),
    ALL('Data'[ID]),
    'Data'[ID]<RowID)


RETURN IF(ISBLANK(LastID),BLANK(),
        ABS(SUM([MyValue]) -
            LOOKUPVALUE('Data'
                [MyValue],
                'Data'[ID],
                LastID)
            )
    )

This measure takes the average of [Moving range] for each row, keeping all filters besides ID
Rich (BB code):
 AverageMovingRange = AVERAGEX(ALL('Data'[ID]),[Moving Range])
 

Excel Facts

Why are there 1,048,576 rows in Excel?
The Excel team increased the size of the grid in 2007. There are 2^20 rows and 2^14 columns for a total of 17 billion cells.
I know it is a bit late but hope this helps! You code is slow because you are using a lot of functions that put load on the Formula Engine of Analysis Services.

Try this


VBA Code:
AverageMovingRange =
VAR DataTable_ =
    CALCULATETABLE (
        Data,
        ALLEXCEPT ( Data, Data[Category] )
    )
VAR Result =
    AVERAGEX (
        ADDCOLUMNS (
            ADDCOLUMNS (
                DataTable_,
                "@Previous Value",
                    VAR CurrentCategory = Data[Category]
                    VAR CurrentID = Data[ID]
                    VAR RowsForCurrentCategory = FILTER ( DataTable_, Data[Category] = CurrentCategory  )
                    VAR PreviousID = MAXX ( FILTER ( RowsForCurrentCategory, Data[ID] < CurrentID ), Data[ID]  )
                    VAR ValueAtPreviousID = SUMX ( FILTER ( RowsForCurrentCategory, Data[ID] = PreviousID ), Data[MyValue] )
                    RETURN ValueAtPreviousID
            ),
            "@MovingRange", IF ( NOT ISBLANK ( [@Previous Value] ), Data[MyValue] - [@Previous Value] )
        ),
        ABS ( [@MovingRange] )
    )
RETURN Result
 
Upvote 0
Solution
I know it is a bit late but hope this helps! You code is slow because you are using a lot of functions that put load on the Formula Engine of Analysis Services.

Try this


VBA Code:
AverageMovingRange =
VAR DataTable_ =
    CALCULATETABLE (
        Data,
        ALLEXCEPT ( Data, Data[Category] )
    )
VAR Result =
    AVERAGEX (
        ADDCOLUMNS (
            ADDCOLUMNS (
                DataTable_,
                "@Previous Value",
                    VAR CurrentCategory = Data[Category]
                    VAR CurrentID = Data[ID]
                    VAR RowsForCurrentCategory = FILTER ( DataTable_, Data[Category] = CurrentCategory  )
                    VAR PreviousID = MAXX ( FILTER ( RowsForCurrentCategory, Data[ID] < CurrentID ), Data[ID]  )
                    VAR ValueAtPreviousID = SUMX ( FILTER ( RowsForCurrentCategory, Data[ID] = PreviousID ), Data[MyValue] )
                    RETURN ValueAtPreviousID
            ),
            "@MovingRange", IF ( NOT ISBLANK ( [@Previous Value] ), Data[MyValue] - [@Previous Value] )
        ),
        ABS ( [@MovingRange] )
    )
RETURN Result

Works perfectly, thank you!
 
Upvote 0

Forum statistics

Threads
1,223,885
Messages
6,175,183
Members
452,615
Latest member
bogeys2birdies

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top