Forum Discussion
Memory issues with filter
- 3 years ago
The performance issue you're experiencing arises from the use of the EARLIER function, especially within a FILTER function that processes row-by-row. When you add a second filter condition using EARLIER, the complexity increases, causing the measure to consume more memory and time.
The EARLIER function is often misunderstood and is a common source of inefficiencies in DAX. When used within a row context, it returns the value of a specified column for the "earlier" row context (outer row context). This can lead to nested iterations and exponential growth in the amount of computation.
Here's a breakdown of your problem:
DATEDIFF calculates the difference between the maximum order date and the current row's order date.
The FILTER function then iterates through all rows to get the maximum order date for orders that occurred before or on the current row's order date.
Adding the second condition makes this calculation more complex, as it now has to compare the ID column for each row as well.
To optimize your DAX calculation:Use Variables: Variables can reduce the number of times a calculation is computed, especially inside a row context.
Revise Logic: Instead of comparing every row with every other row, try to partition the data or use other DAX functions that might be more efficient.
Here's a revised version using variables:BUYING_CYCLE = VAR CurrentOrderDate = 'ORDERS'[ORDER_DATE] VAR CurrentOrderID = 'ORDERS'[ID] VAR PreviousOrderDate = CALCULATE( MAX('ORDERS'[ORDER_DATE]), FILTER( ALL('ORDERS'), 'ORDERS'[ORDER_DATE] < CurrentOrderDate && 'ORDERS'[ID] <> CurrentOrderID ) ) RETURN IF( ISBLANK(PreviousOrderDate), BLANK(), DATEDIFF(PreviousOrderDate, CurrentOrderDate, DAY) )
The performance issue you're experiencing arises from the use of the EARLIER function, especially within a FILTER function that processes row-by-row. When you add a second filter condition using EARLIER, the complexity increases, causing the measure to consume more memory and time.
The EARLIER function is often misunderstood and is a common source of inefficiencies in DAX. When used within a row context, it returns the value of a specified column for the "earlier" row context (outer row context). This can lead to nested iterations and exponential growth in the amount of computation.
Here's a breakdown of your problem:
DATEDIFF calculates the difference between the maximum order date and the current row's order date.
The FILTER function then iterates through all rows to get the maximum order date for orders that occurred before or on the current row's order date.
Adding the second condition makes this calculation more complex, as it now has to compare the ID column for each row as well.
To optimize your DAX calculation:
Use Variables: Variables can reduce the number of times a calculation is computed, especially inside a row context.
Revise Logic: Instead of comparing every row with every other row, try to partition the data or use other DAX functions that might be more efficient.
Here's a revised version using variables:
BUYING_CYCLE =
VAR CurrentOrderDate = 'ORDERS'[ORDER_DATE]
VAR CurrentOrderID = 'ORDERS'[ID]
VAR PreviousOrderDate =
CALCULATE(
MAX('ORDERS'[ORDER_DATE]),
FILTER(
ALL('ORDERS'),
'ORDERS'[ORDER_DATE] < CurrentOrderDate && 'ORDERS'[ID] <> CurrentOrderID
)
)
RETURN
IF(
ISBLANK(PreviousOrderDate),
BLANK(),
DATEDIFF(PreviousOrderDate, CurrentOrderDate, DAY)
)