Power BI Performance Deep Dive #3: DAX Optimierung
Jede:r Power BI Entwickler:in kennt das Problem: Anforderungen werden überarbeitet und komplexer, die zusätzlichen Berechnungsschritte führen dazu, dass einzelne Berechnungen lange laden und damit die Anwender:innen beeinträchtigt werden. Welche Tipps sollten bei der Erweiterung des Datenmodells mittels DAX-Code beachtet werden?
- Verwendung der DAX Funktion DIVIDE statt /: Die Verwendung der DIVIDE(Numerator, Denominator)-Funktion. Sie fängt Divisionen durch Null automatisch ab und ist oft effizienter als eine manuelle IF-Prüfung.
- Vermeidung von FILTER(All(Table), ...): Wenn möglich, sollten die internen Filter von CALCULATE verwendet werden. Ein FILTER über eine gesamte große Faktentabelle ist für die Performance schlicht schlecht.
- Iteratoren (SUMX, AVERAGEX) nur falls nötig einsetzen: Diese Funktionen arbeiten Zeile für Zeile. Wir empfehlen sie nur zu verwenden, falls einfache Aggregation (SUM) nicht ausreicht.
- Einsatz von Measures statt berechneter Spalten: Berechnete Spalten verbrauchen wertvollen RAM und vergrößern das Datenmodell. Man sollte sie nur benutzen, falls die Spalte als Slicer, in einer Beziehung oder für die Vermeidung von Iteratoren benötigt wird.
Welche Auswirkungen nicht performant designte DAX-Abfragen haben, sehen wir am Beispiel der Vermeidung von Iteratoren. Wir verwenden zur Veranschaulichung das AdventureWorks Power BI Dataset.
Wir erzeugen zwei Measures mit derselben Funktion.
Sales_fast = SUM(Sales[Sales Amount])
Sales_Slow =
SUMX(
Sales,
CALCULATE(
SUM(Sales[Sales Amount]),
FILTER(
ALL(Sales),
Sales[SalesOrderLineKey] = EARLIER(Sales[SalesOrderLineKey])
)
)
)
Das Ergebnis dieser Measures ist ident:

Wenn wir mittels der Leistungsanalyse die Ergebnisse berechnen lassen, sehen wir aber deutliche Unterschiede:

Beim Einfügen der Abfragen im empfehlenswerten 3rd Party Tool DAX Studio, Aktivierung der Server Timings

und anschließendem Ausführen der Abfragen, sehen wir, dass sowohl die FormelEngine (FE) als auch die Storage Engine (SE) beim Auswerten des Measures “Sales Slow” sehr lange brauchen, um einen Query Plan zu erstellen und die Berechnung durchzuführen.

Das Ergebnis der Abfrage “Sales_Fast” wiederum ist praktisch augenblicklich vorhanden.

Bei Performanceproblemen von Measures, die Iteratoren verwenden, kann also ein Umwandeln des Measures zu massiven Performanceverbesserungen führen.