Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

The Power BI Data Visualization World Championships is back! Get ahead of the game and start preparing now! Learn more

Reply
Anonymous
Not applicable

DAX Optimizing SUMMARIZE()

Goal: For each account, I am trying to find the average number of days (day_as_timestamp) that each user has activity for subject to a date constraint from a related table (EffSubStartDate).

 

So starting from this:

 

AccountID       user_id   day_as_timestamp 
ABCBill 1/1/21
ABCBill1/5/21
ABCMike1/5/21
   

 

I'd like to compute the number of distinct days for each user for each account and find the account average. In this case

Bill = 2 days,

Mike = 1 day,

so 1.5 days for the account

 

I can do this with SUMMARIZE(), but of course it is very slow. 

 

 

 

 

app_days_per_user = 
VAR User_days =

    SUMMARIZE(
                'Event Detail',
                'Event Detail'[user_id],
                "app_days",
                CALCULATE(
                            DISTINCTCOUNT('Event Detail'[day_as_timestamp]),
                            FILTER(
                                            'Event Detail',
                                            'Event Detail'[day_as_timestamp] > MINX(RELATEDTABLE('SecDB Sites'), 'SecDB Sites'[EffSubStartDate])
                            )
                        )
            )
            
RETURN
    AVERAGEX(User_days, [app_days])

 

 

 

This gets the right result when I add it to a table of accounts but is too slow to use. I've experimented with subbing in ADDCOLUMNS() instead, but I can't figure out how to keep the same account context from above.

 

Any advice on how to optimize this measure?

1 ACCEPTED SOLUTION
AlexisOlson
Super User
Super User

I'd recommend bringing the minimum calculation outside of the FILTER iterator if possible. Maybe like this:

app_days_per_user =
VAR User_days =
    ADDCOLUMNS (
        SUMMARIZE ( 'Event Detail', 'Event Detail'[user_id] ),
        "app_days",
            CALCULATE (
                VAR MinStart =
                    CALCULATE ( MIN ( 'SecDB Sites'[EffSubStartDate] ) )
                RETURN
                    CALCULATE (
                        DISTINCTCOUNT ( 'Event Detail'[day_as_timestamp] ),
                        FILTER (
                            VALUES ( 'Event Detail'[day_as_timestamp] ),
                            'Event Detail'[day_as_timestamp] > MinStart
                        )
                    )
            )
    )
RETURN
    AVERAGEX ( User_days, [app_days] )

View solution in original post

10 REPLIES 10
AlexisOlson
Super User
Super User

I'd recommend bringing the minimum calculation outside of the FILTER iterator if possible. Maybe like this:

app_days_per_user =
VAR User_days =
    ADDCOLUMNS (
        SUMMARIZE ( 'Event Detail', 'Event Detail'[user_id] ),
        "app_days",
            CALCULATE (
                VAR MinStart =
                    CALCULATE ( MIN ( 'SecDB Sites'[EffSubStartDate] ) )
                RETURN
                    CALCULATE (
                        DISTINCTCOUNT ( 'Event Detail'[day_as_timestamp] ),
                        FILTER (
                            VALUES ( 'Event Detail'[day_as_timestamp] ),
                            'Event Detail'[day_as_timestamp] > MinStart
                        )
                    )
            )
    )
RETURN
    AVERAGEX ( User_days, [app_days] )
Anonymous
Not applicable

Good call, that brought the run time down some, I think that may be as good as it gets for what I want to do. Thanks for your help!

Anonymous
Not applicable

Yes, I did experiment with wrapping with an extra calculate which does solve the context issue... but performance-wise it appears to be just a hair better than SUMMARIZE().

How are your tables related? Also, do you have any relevant dimension tables you haven't mentioned?

Anonymous
Not applicable

Event Detail (* to 1) Sites (1 to *) BridgeTbl (* to *)> Accounts

What column relates Event Detail and Sites?

Anonymous
Not applicable

A SiteID relates those two. An account can have multiple sites.

Is it possible to simplify the filter condition to remove MINX? For example, would this work?

FILTER (
    'Event Detail',
    'Event Detail'[day_as_timestamp] > RELATED ( 'SecDB Sites'[EffSubStartDate] )
)

If not, why not? Does a unique site have multiple start dates?

Anonymous
Not applicable

Yes, a site can have multiple start dates

AlexisOlson
Super User
Super User

An ADDCOLUMNS version could look like this:

app_days_per_user =
VAR User_days =
    ADDCOLUMNS (
        SUMMARIZE ( 'Event Detail', 'Event Detail'[user_id] ),
        "app_days",
            CALCULATE (
                CALCULATE (
                    DISTINCTCOUNT ( 'Event Detail'[day_as_timestamp] ),
                    FILTER (
                        'Event Detail',
                        'Event Detail'[day_as_timestamp]
                            > MINX ( RELATEDTABLE ( 'SecDB Sites' ), 'SecDB Sites'[EffSubStartDate] )
                    )
                )
            )
    )
RETURN
    AVERAGEX ( User_days, [app_days] )

 

Note that I'm following the rule of thumb to "wrap any expression for an extended column within a CALCULATE function whenever you move an extended column out from SUMMARIZE into an ADDCOLUMN statement." from Best Practices Using SUMMARIZE and ADDCOLUMNS.

Helpful resources

Announcements
Power BI DataViz World Championships

Power BI Dataviz World Championships

The Power BI Data Visualization World Championships is back! Get ahead of the game and start preparing now!

November Power BI Update Carousel

Power BI Monthly Update - November 2025

Check out the November 2025 Power BI update to learn about new features.

FabCon Atlanta 2026 carousel

FabCon Atlanta 2026

Join us at FabCon Atlanta, March 16-20, for the ultimate Fabric, Power BI, AI and SQL community-led event. Save $200 with code FABCOMM.