I have been wrecking my brain on how to improve my dynamic models, which rely on very large datasets.
The culprit I was able to identify:
Using FILTER() in a CALCULATE() function destroys performance.
This was recently discussed by Chris Webb on his blog.
And even Microsoft themselves will tell you to avoid using FILTER as a filter argument.
(Did they realise how funny that title looks?)
In the same article however, Microsoft tells us:
In this example, the FILTER function must be used. It’s because it requires evaluating the Profit measure to eliminate those months that didn’t achieve a profit. It’s not possible to use a measure in a Boolean expression when it’s used as a filter argument.
And that is exactly my problem:
I run into this limitation all the time. Because most of the models I make are dynamic. By which I mean a slicer filters the data based on for example a Date Selected or similar threshold.
And because the dataset is usually very large, I run into the dreaded Query has exceeded the available resources error far too often.
I see 3 solutions, but I think only the third is going to help me out long term:
- Some alternative DAX pattern (which I haven’t heard of yet)
- Improving everything apart from the CALCULATE&FILTER context (not efficient or effective)
- Restructuring my approach to these dynamic models (in a way I have yet to learn about)
There will probably be a course or 2 on EDNA about (3), but forgive my ignorance as I haven’t found these yet myself.
Demo File
For illustrative purposes, consider the below file.
Note: You will not get the Exceeded Resources error in this file as I am not going to include a +20mb dataset for obvious reasons.
The logic of this Payables Ageing Analysis model relies on the [Days Left] Measure:
Days Left =
//Days left where Selected Date >= Posting Date AND (Selected Date < Clearing Date OR = BLANK)
IF( AND( [Posting Date] <= [DateSelected],
OR([Clearing Date] > [DateSelected], [Clearing Date] = BLANK())),
DATEDIFF( [DateSelected],[Due Date], DAY ),
BLANK() )
[DateSelected] takes from the slicer.
This measure is subsequently used as follows for instance:
_A0_ OverdueAmount =
VAR SelectedColumn = SELECTEDVALUE(SwitchLocalCurrency[CurrencyID])
Var InvoiceValue =
IF(
ISBLANK([Days Left]),
BLANK(),
SUMX(
FILTER(_FACT_BSEG_AP,
[Days Left] < 0
&& _FACT_BSEG_AP[H_BLART_DocumentType]<>"KZ"),
[_A0_ OutstandingAmount]
)
)
And similar measures for NotDue, for grouping by [Days Left] etc.
Most if not all of which require a CALCULATE-FILTER measure using [Days Left].
If the model has only one [DateSelected] (today, for instance), then this isn’t a problem because I can just add a column in the dataset. But that is not what I am trying to do here.
So what am I missing?
Thank you in advance!
Dynamic_Chart_Interaction_Table.pbix (1.0 MB)