Forum Discussion

Anonymous's avatar
Anonymous
Not applicable
6 years ago
Solved

10x slower with ALLEXCEPT vs

I'm calculating a variable and initially used ALLEXCEPT as a filter for MAXX, only to find it was incredibly slow (250 seconds to calculate a single Measure). Switching the logic to CALCULATE with a ...
  • edhans's avatar
    edhans
    6 years ago

    Anonymous They might be returning the same results because of how your visual is, but they are not the same calc at all. This is the filter context (model filter, visuals, slicer, etc) that is returning the same result.

     

    I don't now how big your table is, but ALLEXCEPT() can be very inefficent. Let's say you have 100 columns and 1,000,000 rows. You basically told the model to remove filters on 99 columns. It may be more efficent to use ALL() to remove the filters on just what you need, like below:

    var _prevdate =
    MAXX(
        FILTER(
            ALL(
                Appointments[Field XType]
                Appointments[Field YType],
                Appointments[Appointment Start]
            ),
            Appointments[Appointment Start] < _date
                && NOT (
                    ISBLANK( [Number of appointments] )
                )
        ),
        Appointments[Appointment Start]
    )
    

     

    FILTER() is definitely not your problem. In fact, in your first measure, it is using Filter. It is just syntax sugar that is alowing you to not use the function directly. In the background, it is doing this:

    Measure =
    CALCULATE(
        MAX( Appointments[Appointment Start] ),
        FILTER(
            ALL('Appointments'),
            Appointments[Appointment Start] < _date
        )
    )
    

    Which means you can probably just use this:

    Measure =
    MAXX(
        FILTER(
            ALL( 'Appointments' ),
            Appointments[Appointment Start] < _date
        ),
        Appointments[Appointment Start]
    )
    

     

    CALCULATE() does something called context transition and can be very expensive, and can be necessary. But your measure may not require context transition, so it isn't necessary to do it. I avoid CALCULATE() for this reason unless I know I need it. It doesn't matter on small models with 10,000 records, but it can matter on tables with millions of records depending on what it has to do. There are two chapters on just the intricacies of CALCULATE() in the Definitive Guide to DAX, and even more info in subsequent chapters.

    FILTER() is the most efficent of the DAX measures because everything is a filter for DAX. It is all about tables and filters.