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]

Mind the gap!

Le blog d'aujourd'hui va vous montrer comment utiliser la fonctionnalité de calcul personnalisé de XLCubed pour créer des coupures de colonne dans une grille. Imaginez que vous ayez un rapport qui vous montre les ventes des revendeurs dans toutes les catégories de modèles de produits sur une période de 12 mois.

 

 

 

Il n'y a rien de mal à ce rapport, mais ne pensez-vous pas qu'il serait plus agréable de pouvoir séparer chaque quart de bloc, c'est-à-dire de mettre une colonne de séparation entre mars et avril, juin et juillet, septembre et octobre. Ce serait beaucoup plus facile à lire et cela permettrait de montrer clairement où chaque trimestre commence et se termine.

Commençons donc par créer un calcul personnalisé. Cliquez sur l'icône en surbrillance et donnez un nom à votre calcul personnalisé - appelons-le ColBreak. Il est lié à la hiérarchie Date.Calendrier.

 

Dans la zone Expression, entrez une chaîne vide commençant et se terminant par " (entre guillemets). Cliquez sur OK.

Pour insérer ceci dans notre rapport, nous allons maintenant dans l'éditeur de hiérarchie pour la date du calendrier - développez le membre Tous et vous verrez ColBreak.

Faites glisser ce texte et insérez-le dans le rapport. Nous l'insérerons après mars, juin et septembre et cliquez sur OK.

 

 

Le rapport ressemble maintenant à ceci :

 

Maintenant, formatons cette coupure de colonne de manière à ce que ColBreak n'apparaisse pas en tête de colonne. Vous devez faire un clic droit pour obtenir le menu contextuel de XLCubed et ensuite choisir Formater ce membre.

Nous allons choisir le blanc pour la couleur de la police avant de cliquer sur OK.

Le rapport ressemble maintenant à ceci, avec des démarcations claires entre chaque trimestre :

 

 

 

Solve order shenanigans

Aujourd'hui, je vais tenir un blog sur un problème que nous avons récemment résolu dans un cube de client, une erreur dans le script Mdx qui est très facile à faire si vous ne faites pas attention.

Nous allons présenter un exemple simple dans AdventureWorks (quoi d'autre ?) pour illustrer le problème.

Le client avait déjà ajouté un calcul à son cube pour montrer la croissance d'une année sur l'autre. La formule est la suivante :

Créer le membre CurrentCube [mesures] [Delta à l'année précédente] en tant que
(
    ([Mesures]. [Montant des ventes sur Internet])
    -
    ([Mesures]. [Montant des ventes sur Internet],
        Période Parallèle(
            [Date]. [Calendrier]. [Année civile],
            1,
            [Date]. [Calendrier].Membre actuel
        )
    )
)
/
    ([Mesures]. [Montant des ventes sur Internet],
        Période Parallèle(
            [Date]. [Calendrier]. [Année civile],
            1,
            [Date]. [Calendrier].Membre actuel
        )
    )
, Format_String = "0.00%" ;

(certaines vérifications d'erreurs ont été supprimées pour plus de clarté)

Cette capture d'écran montre quelques grilles XLCubed simples montrant la valeur réelle, et en dessous du pourcentage de variation. J'ai ajouté un calcul Excel pour montrer que les résultats sont conformes aux attentes.

Plus tard au cours du développement du cube, le client a ajouté un membre calculé dans sa dimension Produit, qui donne un total excluant une des catégories de produits.

Pour reproduire cela, je vais ajouter un calcul pour "All Ex Bikes" :

Créer un membre 
CurrentCube. [Produit]. [Catégories de modèles de produits]. [Tous les produits]. [Tous les vélos Ex].
comme
(
    ([Produit]. [Catégories de modèles de produits]. [Tous les produits])
    -
    ([Produit]. [Catégories de modèles de produits]. [Catégorie].& [1])
) ;

Et si nous refaisons le rapport, nous obtenons ce qui suit.

Remarquez la cellule que j'ai mise en évidence. Le calcul "All Ex Bikes" fonctionne bien sur la mesure normale, mais il donne un chiffre totalement faux pour le calcul du pourcentage. Que se passe-t-il ?

Le problème est que, dans la cellule mise en évidence, les services d'analyse doivent tenir compte de deux calculs lorsqu'ils élaborent le résultat.

  • Comparer cette année à l'année dernière
  • Obtenez le "Grand Total", et soustrayez "Vélos"

Comme le nombre de retours est de 1,85 %, nous pouvons voir que le service d'analyse a choisi la deuxième option, "Grand Total" - "Vélos".

Ce que nous voulons vraiment, c'est que le calcul soit fait en obtenant le sous-total, puis en faisant la variation en pourcentage sur cette base.

Heureusement, la solution était simple. Les services d'analyse effectueront les calculs dans l'ordre où ils se trouvent dans le script Mdx. Pour résoudre le problème, nous avons donc simplement déplacé la nouvelle définition de "All Ex Bikes" au-dessus du calcul du pourcentage.

Le nombre de retours correspond maintenant à nos attentes.

L'ordre de passage ou de résolution peut être un sujet complexe, vous devrez donc être prudent.

Dans ce cas, le numéro est totalement faux, donc il était facile à repérer, mais certains insectes seront beaucoup plus subtils, alors attention !