Optimisation DAX : les patterns qui font tomber les rapports Power BI lents
On parle souvent d'optimisation DAX en théorie. Voici les patterns concrets qui reviennent le plus souvent dans les modèles Power BI hérités, et comment les corriger.
Quand un rapport Power BI rame, le réflexe est souvent de blâmer le volume. C'est rarement la vraie cause. Dans la plupart des modèles hérités que je reprends, les performances chutent à cause de quelques patterns DAX classiques, qu'on retrouve presque à chaque mission.
1. Les itérations cachées
Une mesure du type SUMX(table, table[col1] * table[col2]) est parfaitement légitime. Le problème commence quand on en imbrique plusieurs, ou qu'on remplace un SUM simple par un SUMX sur une grande table sans nécessité.
Règle simple : si l'opération peut être écrite avec un agrégat direct sur une colonne, ne passez pas par un itérateur. Et si vous devez itérer, faites-le sur la table la plus petite possible.
2. Les contextes de filtre mal maîtrisés
CALCULATEest l'outil le plus puissant de DAX, et celui qui produit le plus d'effets de bord. Un contexte de filtre modifié sans intention claire peut suffire à transformer une mesure en gouffre de performance ou en valeur fausse.
Trois questions à se poser à chaque CALCULATE :
- Quel filtre j'ajoute, quel filtre je supprime ?
- Est-ce que ce filtre porte sur la table de fait ou sur une dimension ?
- Est-ce que
REMOVEFILTERSouALLsont réellement nécessaires, ou je peux faire plus chirurgical avecKEEPFILTERS?
3. Les variables oubliées
Beaucoup de mesures héritées recalculent plusieurs fois la même sous-expression. Une variable VARaurait pu la calculer une fois et la réutiliser. Sur une mesure utilisée dans une matrice avec 10 000 cellules, l'effet sur la performance est spectaculaire.
// Avant
Sales YoY % =
DIVIDE(
[Sales] - CALCULATE([Sales], DATEADD(Calendar[Date], -1, YEAR)),
CALCULATE([Sales], DATEADD(Calendar[Date], -1, YEAR))
)
// Après
Sales YoY % =
VAR _ly =
CALCULATE([Sales], DATEADD(Calendar[Date], -1, YEAR))
RETURN
DIVIDE([Sales] - _ly, _ly)4. Les colonnes calculées qui auraient dû être des mesures
Une colonne calculée est évaluée à chaque refresh, stockée en mémoire, et augmente la taille du dataset. Une mesure est évaluée à la volée et ne pèse rien en mémoire. Quand un calcul peut être une mesure, ça doit être une mesure.
5. Les modèles aplatis
Un modèle en étoile bien construit, avec une table de faits centrale et des dimensions clairement séparées, est presque toujours plus performant qu'une grande table aplatie. Les modèles hérités ont souvent dérivé vers des tables larges parce que c'était plus simple à charger, mais ils paient cette dette à chaque rendu.
L'optimisation DAX n'est pas un travail de virtuose. C'est une discipline d'hygiène : nommer, isoler, réutiliser, mesurer.
Mesurer avant d'optimiser
Dernier point, et le plus important : on ne peut pas optimiser ce qu'on ne mesure pas. Performance Analyzer dans Power BI Desktop, DAX Studio, et la trace SQL Profiler sur Analysis Services sont les trois outils que j'utilise systématiquement. Toute optimisation non chiffrée est un acte de foi.
Une situation similaire chez vous ?
Décrivez votre contexte, je reviens vers vous sous 1 jour ouvré.