[MDX] NON EMPTY, NonEmpty(), NonEmptyCrossJoin()… Kézako?

Je tiens à le dire tout de suite, je ne suis pas vraiment un cador en MDX. J’essaie de m’y mettre, sous l’impulsion conjointe du grand et fort Romuald Coutaud, et du moins grand mais tout aussi fort Gurvan Guyader, dont le talent dans le domaine n’est plus à démontrer contrairement à ses dires trop modestes.

Mais revenons au sujet. J’ai eu récemment la question suivante en formation: « Qu’est ce qui remplace NonEmptyCrossJoin, sachant que cette fonction est marquée comme dépréciée depuis 2005?« .
Cette fonction introduite en AS 2000 permet d’éliminer les tuples vides du résultat de l’intersection des différents sets fournis en paramètre. Ses performances sont remarquables mais celle ci ne fait pas partie du standard.

Ma courte connaissance du MDX sur le sujet se limite à savoir que pour effectuer cette opération en post-2000 on dispose de deux méthodes principales: le mot clé NON EMPTY et la fonction NonEmpty(), et que cette dernière est plus performante – j’ai encore le souvenir vivace et douloureux d’une requête passant de 10 minutes à 2 secondes en la redesignant avec NonEmpty…

C’est justement Gurvan qui m’a donné l’explication: la fonction NonEmptyCrossJoin est effectivement très rapide: elle peut. Son principe général est de scanner la table de faits directement, et donc de passer outre toutes les opérations pouvant être effectuées en aval, au niveau du cube (CustomRollup, UnaryOperators, Calculations…). Elle peut donc renvoyer des résultats erronés et c’est pourquoi elle a été remplacée par la fonction NonEmpty(), qui elle ne scanne la table de faits qu’après avoir réalisé une analyse de dépendances sur les sets en question.

Pour citer Mosha: « The NonEmpty function works with the cube, not with fact table, therefore it takes into account all calculations defined in the cube. But NonEmpty doesn’t sacrifices performance. It can automatically detect when the space covered by the sets doesn’t have any calculations defined on it, and then it goes directly to fact table just like NonEmptyCrossJoin would. »

Le successeur « logique » de NonEmptyCrossJoin est donc NonEmpty. Le mot clé NON EMPTY (que l’on retrouve dans les requêtes générés par le designer de SSRS par exemple) grève les performances car il ne réalise le filtrage sur le ResultSet qu’au moment du retour, et opère donc la requête sur tous les enregistrements, même vides: si vous avez un membre calculé il sera évalué pour tous les enregistrements, même les vides, avant d’être renvoyé par le Query Execution Engine et filtré pour la présentation.

Pour éviter cette situation, on peut utiliser le NON_EMPTY_BEHAVIOUR d’une mesure calculée pour indiquer à l’optimiseur que celle ci dépend de telle ou telle mesure réelle, et donc ne pas l’évaluer si la mesure réelle évalue à null.

Merci encore une fois à Gurvan et à Mosha pour cette explication conjointe😉

A bientôt!

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s