Analyzing and fixing the issues


NOTE: When you have a valid account, you can test DAX Optimizer without activating any license using the sample models.

Start the analysis using the model Contoso 1M - currency conversion in the Sample Walkthrough workspace.

The Overview page shows the issues found by DAX Optimizer in the file.

Open issues in Dax Optimizer - Overview page

The Issues page shows the list of issues detected.

Open issues in Dax Optimizer - Issues page

The Measures page shows the list of all the measures in the model. The measures affected by an issue are displayed with a red dot.

Open issues in Dax Optimizer - Measures page

DAX Optimizer sorts issues by Relevance as a default. These are the ones that have a higher impact on the performance of the model.

In this particular case, the measure with the highest impact is Sales Amount.

Issues in Dax Optimizer

By clicking on the measure name, DAX Optimizer shows the issue details.

The list of issues provides details about the relative impact on the performance of the measure.

To know more about the issue, visit the knowledge base or click on the Right Arrow in the Content transition in iterator section to expand the issue description. Issues in Dax Optimizer - DAX code

By expanding the issue description, DAX Optimizer shows a more detailed explanation and examples of the code that you can use to fix similar issues.

Issues in Dax Optimizer - DAX code

Issues in Dax Optimizer - solution examples

In this case, the issue is related to the callbacks in a SUMX iterator, which is a common anti-pattern in DAX.

Among the proposed examples to optimize your code, choose the one that better represents the structure of your code.

NOTE: The proposed code examples are general code examples. To fix the particular issue you are facing, you need to readapt the proposed code to your particular case. Among the proposed ones, we suggest choose the one that better represents the structure of the DAX code you have written.

Go to your model editor, change the DAX code accordingly to the proposed example by DAX Optimizer that best represents your situation, and load another version of the model in DAX Optimizer by clicking on + Version.

NOTE: If you are following this sample walkthrough guide by reading this guide and confronting it to the pre-loaded models without adding the fixed model, at this point you have to switch to the V2 of the Contoso 1M - currency conversion model.

Then, mark as fixed the issue in DAX Optimizer. In this specific case, because the code change also removed the iterator, you have to mark as fixed even the second issue.

Fixed issues in Dax Optimizer

Now, go to the Measures page, and filter for the measures that have issues by clicking on Show Only Measures with Issues.

Issues in Dax Optimizer

The remaining measures with open issues have a smaller relevance. However, this does not mean that they are not important. They simply have a lower priority compared to other measures, but once the measures with higher priority are fixed, the focus can be on the other remaining measures.

Measures in Dax Optimizer

Now, in this case, there are five measures with a more detailed relevance. In reality, the relevance did not change: it is only normalized to a different scale to make the numbers easier to compare.

You can now focus on the Margin Currency measure, which has two issues of the same type.

Issues in Dax Optimizer

In this case, you should reduce the cardinality of the iterator, because you cannot assume that the result will be the same by moving a measure outside of the iterator. In this case, the result of Conversion Rate seems to depend on the Sales[Currency Code] column because of the CALCULATE function. However, you should verify whether there are other dependencies.

By clicking on Conversion Rate, you can see the corresponding DAX definition.

Issues in Dax Optimizer

Repeat this process with LastCurrencyDate and AverageRate , to make sure you are aware of the dependencies involved.

Issues in Dax Optimizer

Issues in Dax Optimizer

From the code analysis, we can establish that Conversion Rate depends on the Date and Currency Exchange tables. The Date table is not directly referenced in the Margin Currency code. However, you should check also the relationships in the data model, because, by iterating Sales, the context transition is applied to the expanded table, which expands the table by including all the columns on the one side of any relationship.

The relationship diagram is necessary to evaluate this aspect.

Tables diagram

The Sales table has a relationship with the Date table, which means that when you iterate Sales, for every context transition on Sales you also filter one row in Date. Therefore, we can reach to the conclusion that the Conversion Rate measure depends on Dat[Date] and Sales[Currency Code]. If you authored the measures, you might already know that, but it is always a good idea to check these dependencies before trying to write a more efficient version of the same code.

The following is the actual DAX code, with the Sales tables highlighted in the SUMX iterator.

CALCULATE (
    SUMX ( 
        Sales,
        VAR _CurrencyCode = Sales[Currency Code]
        RETURN 
            [Margin]
                * CALCULATE ( 
                    [Conversion Rate], 
                    'Currency Exchange'[FromCurrency] = "USD",
                    'Currency Exchange'[ToCurrency] = _CurrencyCode 
            )
    )
)

The solution you can choose can be similar to the Example 3 of the Context transition in iterator issue.

Issues in Dax Optimizer

You can generate a table with the unique values of the columns included in the dependencies for the measures inside the iterator. This change should be enough to reduce the complexity of the calculation and improve the performance.

CALCULATE (
    SUMX ( 
        SUMMARIZE ( Sales, 'Date'[Date], Sales[Currency Code] ),
        VAR _CurrencyCode = Sales[Currency Code]
        RETURN 
            [Margin]
                * CALCULATE ( 
                    [Conversion Rate], 
                    'Currency Exchange'[FromCurrency] = "USD",
                    'Currency Exchange'[ToCurrency] = _CurrencyCode 
            )
    )
)

You can now mark Margin Currency as fixed for both issues.

Issues in Dax Optimizer

Repeat a similar optimization for Sales Amount Currency and Total Cost Currency.

The measure Margin Currency % has a different issue, instead.

Issues in Dax Optimizer

The provided example shows how to transform a division within IFERROR in a DIVIDE function.

Issues in Dax Optimizer

Here is the code of the initial Margin Currency % measure:

IFERROR ( [Margin Currency] / [Sales Currency], BLANK() )

Modify the definition as follows:

DIVIDE ( [Margin Currency], [Sales Currency], BLANK() )

You can now mark the issue on Margin Currency % as fixed.

Issues in Dax Optimizer

Returning to the Issues page, there are now three issues on two measures that have not been fixed yet. However, the relevance of the remaining issues seems very small compared to the issues that we already fixed.

You can continue fixing measures until there are no more issues in the model, but the optimizations already made should have a significant impact on the performance of the model.

In fact, you might have already achieved an optimization goal that is good enough for your requirements: you decide when to stop the optimization process.

Now you can validate how the measures fixed have improved the performance of the model by loading your optimized model as a new version.

Note that the Unverified badge highlights that the model has measures that have been declared as fixed, but they have not been verified yet by DAX Optimizer.

Unverified model in Dax Optimizer

The final state of the fixed measures is version 2 (v2) of the model Contoso 1M - currency conversion optimized.

You can now continue the analysis by verifying the fixed issues.

Last update: May 27, 2024