Forum Discussion

anagnostes's avatar
anagnostes
Frequent Visitor
9 years ago
Solved

Memory issues with filter

Hi,   I have a MODEL where I have a Customers table and an Orders Table. I want to add a new mesure in the Customers table where i want to compute the average buying cyle. So i add this DAX mesure:...
  • technolog's avatar
    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)
        )