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

Register now to learn Fabric in free live sessions led by the best Microsoft experts. From Apr 16 to May 9, in English and Spanish.

Reply
nandanu
Frequent Visitor

Need help with DAX query running out of resources

Hi All,

 

Urgently need your help with a special case which is causing a DAX query for a measure to run out of resources. I've been stumped for days and don't know what I'm doing incorrectly.

Here are the details:

nandanu_0-1683665264786.png

Dataset has a table with approx 250k rows. Subset is displayed here. First slicer filters all records where ExpiryDate falls in that range. Second slicer is to set an upper range for the ProcessedDate.

TransactionIDBatchBatchYearEffectiveDateExpiryDateProcessedDateStatus
245467Batch20153420229/16/20229/16/20239/16/2022Lost
245466Batch20153420229/16/20229/16/20239/16/2022Lost
245464Batch20153420229/16/20229/16/20239/16/2022Lost
245463Batch20153420229/16/20229/16/20239/16/2022Lost
245404Batch20153420229/16/20229/16/20239/16/2022Bound
245401Batch20153420229/16/20229/16/20239/16/2022Lost
245392Batch20153420224/1/20229/16/20229/14/2022Bound
245385Batch20153420224/1/20229/16/20229/14/2022Bound
230249Batch20153420224/1/20229/16/20224/1/2022Bound
230230Batch20153420219/16/20219/16/20229/16/2021Bound
215515Batch20153420209/16/20209/16/20219/21/2020Bound
215506Batch20153420199/16/20199/16/20209/16/2019Bound
215496Batch20153420189/16/20189/16/20199/24/2018Bound
185668Batch20153420179/16/20179/16/20189/16/2017Bound
185658Batch20153420169/16/20169/16/20179/16/2016Bound
185647Batch20153420159/16/20159/16/20169/16/2015Bound
       
234054Batch111437202110/5/202110/5/202810/6/2021Lost
233845Batch111437202110/5/202110/5/202210/6/2021Lost
229572Batch111437202110/5/202110/5/202210/6/2021Bound
213124Batch111437202010/5/202010/5/202110/23/2020Bound
213114Batch111437201910/5/201910/5/202010/5/2019Bound
213105Batch111437201810/5/201810/5/201910/9/2018Bound
182342Batch111437201710/5/201710/5/201810/12/2017Bound
182332Batch111437201610/5/201610/5/201710/5/2016Bound
182322Batch111437201510/5/201510/5/201610/5/2015Bound
182312Batch111437201410/5/201410/5/201510/6/2014Bound

 

The colored rows are the ones that fall in the expiry date range for the above slicer.  The max transaction id in that range is the ExpiringTransactionId for that Batch. The objective is to find the RenewalTransactionId for each Batch where it's the maximum Bound transaction greater than the ExpiringTransactionId or, if no Bound transaction is found then the minimum Lost transaction greater than the ExpiringTransactionId. See colored rows above for the two cases.

 

The measures are:

 

ExpiringTransactionId =
VAR startExpirationPeriod = FIRSTDATE(DateTable2[Date])
VAR endExpirationPeriod = LASTDATE(DateTable2[Date])
RETURN
    CALCULATE(
        MAX(Transaction[TransactionID]),
        Transaction[ExpiryDate] >= startExpirationPeriod && Transaction[ExpiryDate] <= endExpirationPeriod,
        Transaction[Status] = "Bound",
        REMOVEFILTERS(Transaction[BatchYear])
    )

RenewalTransactionId =
    VAR maxProcessedDate = LASTDATE(DateTable1[Date])
    VAR expiringTransactionId = [ExpiringTransactionId]

    // Find the max transaction id within the max processed date limit after the expiring transaction id where status is Bound
    VAR maxTransactionIdBound =
        CALCULATE(
            MAX(Transaction[TransactionID]),
            Transaction[ProcessedDate] <= maxProcessedDate,
            Transaction[TransactionID] > expiringTransactionId,
            Transaction[TransactionStatus] = "Bound",
            REMOVEFILTERS(Transaction[BatchYear])
        )

    // Find the min transaction id within the max processed date limit after the expiring transaction id where status is Lost
    VAR maxTransactionIdLost =
        CALCULATE(
            MIN(Transaction[TransactionID]),
            Transaction[ProcessedDate] <= maxProcessedDate,
            Transaction[TransactionID] > expiringTransactionId,                        
            Transaction[TransactionStatus] = "Lost",
            REMOVEFILTERS(Transaction[BatchYear])
        )

RETURN
    // If a valid Bound transaction id is found take that else go with the Lost transaction id.
    IF(
        NOT ISBLANK(maxTransactionIdBound),
        maxTransactionIdBound,
        maxTransactionIdLost
    )

The calculation for RenewalTransactionId when executed over the entire dataset of 250k rows results in the dreaded "Out of Resources" error. How can I rewrite it to be efficient in performance?

Thanks in advance for your help!
3 REPLIES 3
ppm1
Solution Sage
Solution Sage

A couple quick things to try:

1. IF.EAGER instead of IF

2. MAX instead of LASTDATE

 

Also see these videos for how to troubleshoot your slow visual and some design alternatives to consider. How many rows does your visual return? That is likely a big part of the problem.

 

https://www.youtube.com/watch?v=ScJVQoOWSqc&t=1s

https://www.youtube.com/watch?v=nNHSic2kDjM

 

Pat

Microsoft Employee
some_bih
Super User
Super User

Hi @nandanu you should try to optimize your code. Best practice is to use DAX Studio to measure performance of storage and formula engine, overall timing ... with one code set and comparing it with changed scenario.

Firstly, without changing your code:

Usually number or rows are not issue for performance, it is big number of columns. Analyse your columns, if there are some unused columns simple remove them and check your performance.

 

Second: Try to create data on level which could be ok with Power Query transformation, like group or something

 

Third: Using FIRST/LAST DATE function could be replaced with Min/Max in some scenarios.

Great article explaining this could be found https://www.sqlbi.com/articles/understanding-the-difference-between-lastdate-and-max-in-dax/ 

and this one https://www.sqlbi.com/blog/marco/2013/10/22/difference-between-lastdate-and-max-for-semi-additive-me... (here you can find how to rewrite LASTDATE using Max).

Other: try to create data on level which could be ok with Power Query transformation

I hope this could help





Did I answer your question? Mark my post as a solution!

Proud to be a Super User!






Hi @some_bih,

 

Thanks for your help with this issue. I have used DAX studio to track SE and FE load and it has helped somewhat. The xmSQL generated is beyond my expertise but it did help with optimizing the query by analyzing the cardinality of the comparisons (comparing IDs vs dates). 

 

Your suggestion about replacing FIRSTDATE/LASTDATE with MIN/MAX does seem to have helped a bit. But I still get the out of resources error when the report is run over the entire dataset. For now, we are getting around this issue by having users filter the dataset to a limited period that is relevant to the Expiring Between and As Of Date filters. 

Helpful resources

Announcements
Microsoft Fabric Learn Together

Microsoft Fabric Learn Together

Covering the world! 9:00-10:30 AM Sydney, 4:00-5:30 PM CET (Paris/Berlin), 7:00-8:30 PM Mexico City

PBI_APRIL_CAROUSEL1

Power BI Monthly Update - April 2024

Check out the April 2024 Power BI update to learn about new features.

April Fabric Community Update

Fabric Community Update - April 2024

Find out what's new and trending in the Fabric Community.