Conseils sur les performances DAX - leçons tirées du terrain

XLCubed supporte une interface glisser/déposer pour la création de rapports par rapport aux services d'analyse tabulaire depuis la première version du nouveau moteur. Il permet aux utilisateurs de créer facilement des rapports qui exécutent des requêtes DAX sur le cube, et nous avons souvent constaté de très bonnes performances chez les clients lorsque le MDX contre Tabular était la cause de longs rapports.

Ainsi, lorsque nous avons été contactés à SQL Pass à Seattle par des participants qui avaient un problème de performance du SSAS Tabular, nous étions optimistes quant à notre capacité à les aider.

Dans ce cas, l'entreprise voulait récupérer des milliers de lignes du cube au niveau transactionnel, et la première approche avait été d'utiliser des tableaux croisés dynamiques dans Excel. Pour atteindre le niveau le plus bas, ils ont croisé les niveaux les plus bas de toutes les hiérarchies sur la section des lignes, ce qui a donné le bon résultat, mais la performance était terrible, plusieurs requêtes prenant 20 minutes ou plus et d'autres ne revenant pas du tout.

Nous espérions que l'utilisation d'une table XLCubed fonctionnant en DAX serait la solution et avons créé le même rapport dans le concepteur. Malheureusement, si les performances étaient un peu meilleures, elles étaient encore loin d'être acceptables ; le modèle était grand, et le nombre de colonnes combiné à leur cardinalité signifiait que beaucoup de travail était effectué sur le serveur.

Le générateur DAX de XLCubed essayait de croiser toutes les valeurs de chaque colonne, ce qui avait bien fonctionné pour nos autres clients. Mais lorsqu'il y a une douzaine de colonnes incluant l'ID de la transaction, les choses ne se passent pas si bien. Le DAX en lui-même n'est pas une solution miracle et les modèles tabulaires SSAS peuvent rencontrer des problèmes de performance sur des données de bas niveau - nous avions besoin d'une nouvelle approche.

Après quelques recherches, nous avons discuté de la question et de nos réflexions avec nos amis de SQLBI et avons déterminé qu'au lieu d'utiliser la fonction cross-join, nous voulions une option permettant d'utiliser Summarize(), car celle-ci n'utilise que les lignes de la base de données et peut accéder aux colonnes liées au tableau récapitulatif qui sont nécessaires pour le rapport.

Comme le rapport du client contenait l'ID de la transaction, le résultat n'a pas été agrégé, même si nous avons utilisé la fonction de résumé. Mais nous voulions également ajouter un véritable rapport de transaction, en utilisant la fonction Related().

Enfin, SQL 2016 ajoute quelques nouvelles fonctions, SummarizeColumns() et SelectColumns(), qui sont toutes deux utiles pour ce type de rapport, mais offrent de meilleures performances que les anciens équivalents.

Le résultat final dans XLCubed est une nouvelle option pour les tables DAX permettant aux utilisateurs de définir le type de rapport qu'ils veulent exécuter, et quelques changements internes afin que XLCubed utilise automatiquement la fonction DAX la plus efficace là où elle est disponible.

Une version bêta a été envoyée aux utilisateurs professionnels et les résultats ont été fantastiques. Le rapport qui avait duré plusieurs minutes s'est maintenant terminé en quelques secondes, et 20 minutes sont passées à 15 secondes - nous avons eu des utilisateurs très heureux !

Les changements seront apportés dans la prochaine version de XLCubed afin que tous nos clients puissent bénéficier des améliorations. C'est toujours agréable quand une demande d'un client contribue à améliorer le produit pour tout le monde.

Un exemple de changement de syntaxe est présenté ci-dessous

Avant :

 

ÉVALUER
FILTRE (
    ADDCOLUMES (
        FILTRES DE GARDE (
            CROSSJOIN ( VALEURS ("Client" [Éducation] ), VALEURS ("Produit" [Couleur] )
        ),
        "Unités totales Internet", "Ventes par Internet" [Unités totales Internet],
        "Ventes totales sur Internet", "Ventes sur Internet" [Ventes totales sur Internet]
    ),
    PAS ISBLANC ( [Unités totales Internet] )
)
ORDRE DE
    Client" [Éducation],
    Produit" [Couleur]

Après :

 

ÉVALUER
FILTRE (
    ADDCOLUMES (
        FILTRES DE GARDE (
            RÉSUMÉ ("Ventes sur Internet", "Client" [Éducation], "Produit" [Couleur] )
        ),
        "Unités totales Internet", "Ventes par Internet" [Unités totales Internet],
        "Ventes totales sur Internet", "Ventes sur Internet" [Ventes totales sur Internet]
    ),
    NOT ISBLANK ( [Internet Total Units] ) || NOT ISBLANK ( [Internet Total Sales] )
)
ORDRE DE
    Client" [Éducation],
    Produit" [Couleur]