Meilleures pratiques

Voici quelques meilleures pratiques de conception de règles métier, abordant notamment l'utilisation des bonnes commandes, l'utilisation de la syntaxe, les règles d'optimisation, les niveaux de calcul recommandés, les options d'agrégation et une méthodologie de débogage.

Paramètre d'environnement

Prenez en compte les meilleures pratiques suivantes lors de l'utilisation des commandes qui indiquent à une règle métier comment exécuter le calcul.
  • SET UPDATECALC OFF désactive le calcul intelligent, qui est une meilleure pratique pour les règles métier qui utilisent des opérateurs inter-dimensionnels et qui peuvent comporter plusieurs utilisateurs accédant aux mêmes combinaisons de blocs de données. L'utilisation de cette commande est une pratique recommandée pour les applications dans lesquelles plusieurs utilisateurs écrivent dans la base de données. Si vous utilisez le calcul intelligent, veillez à ce qu'il génère les résultats attendus.
  • SET AGGMISSG OFF doit être défini pour les applications pour lesquelles les versions sont des cibles standard ou pour lesquelles des régions de données non feuilles sont utilisées et ne peuvent pas être exclues pendant le calcul.

    L'utilisation de SET AGGMISSG ON est bénéfique si la conception de l'application comporte une configuration de versions ascendantes standard où les données sont chargées au niveau 0.

  • SET NOTICE et SET MSG SUMMARY doivent uniquement être utilisés dans les environnements de développement pour l'analyse de calcul individuel. Ces commandes doivent être enlevées pour les environnements de production ou une fois l'analyse de calcul terminée.
  • SET EMPTYMEMBERSETS ON doit être utilisé lorsque des invites d'exécution sont incluses dans des instructions FIX afin que les ensembles vides ne soient pas calculés. Cela empêche l'exécution d'un calcul sur tous les membres lorsque l'ensemble est vide.

Remarques concernant l'optimisation et les performances

  • Utilisez des modèles dans les règles métier afin d'éviter la répétition de sections de code et d'utiliser au mieux les invites d'exécution.
  • Vérifiez les dépendances sur les membres de calcul dynamique dans chaque calcul. Si possible, modifiez le calcul pour éviter d'inclure l'utilisation répétée du calcul dynamique ou d'enlever ce dernier.
  • Utilisez des instructions FIX et IF pour focaliser votre calcul afin de s'assurer que seules les données requises sont calculées.
  • Evitez de créer un résultat de données égal à 0 (zéro), sauf si vous voulez voir un zéro ; par exemple pour les niveaux de stock. Cela entraîne la création d'un bloc, qui est inclus dans toutes les instructions FIX et IF et calculé. Enlevez les zéros du chargement de données, si possible, ou empêchez la création de zéros dans les règles métier.
  • Evitez d'employer la logique booléenne dans l'instruction IF utilisée pour vérifier si une condition existe. Par exemple, remplacez
    IF (("Budget" ==#missing) OR ("Budget" ==0))
    par ce qui suit, qui génère le même résultat mais évite l'utilisation de la logique booléenne :
    IF ("Budget" +1==1) or IF (Budget/Budget ==#missing)
  • Lorsque cela est possible, exécutez des calculs denses avant d'exécuter des calculs dispersés. Les calculs denses ne créent pas de blocs contrairement aux calculs dispersés. Lorsque vous exécutez des agrégations, pour obtenir le total d'un calcul d'allocation par exemple, veillez à agréger uniquement la section des données requise pour ce calcul d'allocation.
  • Réduisez les passes dans une base de données.
  • Evitez les formules récursives. Une récursivité excessive peut créer des problèmes de performances et exiger que vous effaciez des valeurs pour générer des résultats cohérents.

Procédure pour éviter une erreur de récursivité

Le calcul simultané des calculs dynamiques denses non inclus dans l'en-tête de colonne, y compris dans les membres non inclus dans l'instruction FIX, est le principal motif de l'erreur de récursivité. La récursivité survient si certains des autres membres calculés dynamiquement ont une formule qui inclut le membre dense dans l'instruction FIX. Une erreur de récursivité est générée s'il existe plus de 128 niveaux de récursivité.

L'amélioration des performances est le principal motif de l'exclusion des membres de calcul dynamique. De plus, exclure les membres de calcul dynamique vous permet d'éviter l'erreur de récursivité en assurant que l'export utilise le bloc compressé au lieu du bloc développé. Cette erreur peut également être évitée en modifiant la dimension dense utilisée comme en-tête de colonne pour laquelle chaque colonne définie par l'instruction FIX est calculée individuellement. La récursivité ne survient pas car d'autres calculs dynamiques denses non inclus dans l'instruction FIX sont ignorés, ce qui permet l'exécution de la règle.

Remarque :

Vous ne pouvez pas modifier l'en-tête de colonne de la dimension dense si le fichier d'export contient plus de 256 colonnes.

Par exemple, vous pouvez obtenir l'erreur Calcul impossible. Erreur Essbase (1200494) : erreur lors de l'exécution de la formule pour [Yield%] (ligne 15). Limite de récursivité [128] atteinte si vous utilisez le script de calcul suivant :

SET DataExportOptions
     {
     DATAEXPORTCOLFORMAT ON;
     DATAEXPORTDIMHEADER ON;
     DATAEXPORTDRYRUN OFF;
     DataExportRelationalFile OFF;
     DataExportNonExistingBlocks OFF;
     DataExportLevel ALL;
     DATAEXPORTCOLHEADER "Period";
     DATAEXPORTOVERWRITEFILE ON;
     DataExportDynamicCalc ON;
     };

FIX ("Yield%",@Relative("Change Over",0),@Relative("Currency",0),@Relative("Entity",0),@Relative("Product",0),@Relative("CostCentre",0),"Jan","Actual_Total",@Relative("View",0),"Working","Fy20")

DATAEXPORT "File" "," "/u03/inbox/data/ExportDataFile.txt"  "#";
 

Pour éviter l'erreur, désactivez l'option Dynamique en remplaçant DataExportDynamicCalc ON; par DataExportDynamicCalc OFF;.

Utilisation des instructions FIX

  • Les instructions FIX sont utilisées pour focaliser la règle métier (maintenez le nombre de blocs en cours de calcul aussi bas que possible) afin de s'assurer que seuls les blocs requis sont calculés.
  • Une instruction FIX est recommandée pour les dimensions dispersées car elle réduit le nombre de blocs requis pour le calcul.
  • Assurez-vous que les calculs sont effectués au niveau 0 de toutes les dimensions si la conception de l'application comporte une configuration de versions ascendantes.
  • Lorsque cela est possible, utilisez des instructions FIX externes sur les dimensions dispersées et des instructions IF internes sur les dimensions denses.
  • Toutes les instructions FIX doivent inclure les membres de toutes les dimensions autres que celles comprises dans le calcul. Si une dimension est exclue, tous ses membres sont inclus. Cela peut ne pas être utile.
  • Imbriquez les instructions FIX lorsque cela est possible pour réduire le nombre de passes de la base de données. Chaque instruction FIX complète requiert une passe sur la base de données. Par exemple, vous pouvez utiliser une instruction FIX externe pour une dimension Version, Scénario et toute autre sélection de dimension qui est statique dans l'ensemble de la règle métier.
  • Pour les règles métier associées à des formulaires Web, utilisez la page sélectionnée et des membres de PDV dans les instructions FIX afin de réduire le nombre de blocs calculés.

Utilisation des instructions IF

  • Une instruction IF peut être utilisée dans une formule de membre ; ce n'est pas le cas d'une instruction FIX.
  • Une instruction IF doit être utilisée dans des instructions FIX pour réduire le nombre de blocs auxquels il faut accéder. L'instruction IF met tous les blocs de l'instruction FIX dans la mémoire.
  • Lorsque cela est possible, utilisez des instructions FIX externes sur les dimensions dispersées et des instructions IF internes sur les dimensions denses.
  • Utilisez une instruction ELSE au lieu d'une combinaison d'instructions NOT et ELSEIF lorsque cela est possible pour éviter une analyse inutile des valeurs de membre pendant le calcul. N'utilisez pas d'instruction ELSE si elle n'est pas requise.
  • Vérifiez le choix du bloc de membre de calcul pour déterminer si vous pouvez utiliser un membre dispersé sans dépendances de calcul dynamique.
  • Si possible, ordonnez les instructions IF où le plus grand nombre de cas correspond à la première instruction IF dans le bloc. Utilisez NOT dans l'instruction IF à cette fin, le cas échéant.

    Considérez le script suivant, qui suppose que SalesYTD est un enfant de Ratios dans Sample.Basic (où Comptes et Temps sont des dimensions denses).

    SET UPDATECALC OFF;
    "SalesYTD"(
    IF(@ismbr("Jan"))
        "SalesYTD" = "Sales";
    Else
        "SalesYTD"="Sales" + @prior("SalesYTD");
    Endif)

    Dans cet exemple, alors que 11/12e des données répondent à la condition ELSE, seulement 1/12e des données répond à la condition IF. De plus, le membre SalesYTD est calculé en mode cellule, ce qui signifie que Jan est calculé en premier quel que soit l'ordre de l'instruction IF car il apparaît en premier dans l'outline. Vous pouvez optimiser ce script en utilisant NOT dans l'instruction IF comme illustré dans l'exemple suivant :

    SET UPDATECALC OFF;
    "SalesYTD"(
    IF(NOT(@ismbr("Jan")))
        "SalesYTD" = "Sales" + @prior("SalesYTD");
    Else
        "SalesYTD"="Sales";
    Endif)

Calcul de bloc

  • Utilisez des invites d'exécution pour vous assurer que seules les données requises sont incluses dans la règle métier.
  • Agrégez ou calculez uniquement les données requises à chaque étape du calcul pour garantir que le nombre de blocs inclus dans le calcul est aussi bas que possible pendant aussi longtemps que possible.

Niveaux de calcul

  • Assurez-vous que les calculs sont effectués au niveau 0 de toutes les dimensions si la conception de l'application comporte une configuration de versions ascendantes.
  • Si cela est nécessaire pour le processus d'approbation uniquement, incluez des agrégations dans le type de plan BSO. Déplacez toutes les autres agrégations vers le type de plan ASO.
  • Maintenez le nombre de blocs inclus dans vos calculs aussi bas que possible et pendant aussi longtemps que possible.

Remarques concernant la syntaxe

  • Utilisez toujours @LEVMBRS plutôt que @RELATIVE dans le cadre de la dimension entière.
  • Utilisez @CHILDREN au lieu de @RELATIVE, le cas échéant.
  • Utilisez @REMOVE et @LEVMBRS si vous voulez uniquement exclure certains membres de l'instruction FIX.
Exécution de calculs à l'aide de dates stockées dans Planning

Planning vous permet de saisir des valeurs de date. Par exemple, en utilisant le format MM/DD/YYYY, vous pouvez saisir la date de début 11/01/2019 et la date de fin 06/01/2020. Essbase stocke les valeurs de date formatées comme des valeurs numériques. Par exemple, la date de début précédente est stockée sous la forme 20191101 et la date de fin sous la forme 20200601. Vous pouvez utiliser des fonctions Essbase, comme @ROUND, @INT ou @TRUNCATE, pour calculer le nombre de mois entre n'importe quelle date de début et date de fin. L'exemple suivant montre comment calculer le nombre de mois entre une date de début et une date de fin à l'aide de la fonction @ROUND :

  1. Calculez le nombre de mois entre l'année de la date de fin et l'année de la date de début comme suit :
    (@ROUND ("End Date",-4) - @ROUND ("Start Date",-4))/10000*12
    Le résultat du calcul (20200000 – 20190000)/10000 *12 est 12.
  2. Calculez le nombre de mois entre le début de l'année de la date de fin et la date de fin, puis ajoutez-le.
    (@ROUND ("End Date",-2) - @ROUND ("End Date",-4))/100
    Le résultat du calcul (20200600 – 20200000)/100 est 6.
  3. Calculez le nombre de mois entre le début de l'année de la date de début et la date de début, puis soustrayez-le.
    (@ROUND ("Start Date",-2) - @ROUND ("Start Date",-4))/100
    Le résultat du calcul (20191100 – 20190000)/100 est 11.
  4. Combinez les étapes précédentes dans une formule (12+6-11) pour calculer le nombre de mois (7) entre la date de début et la date de fin.
    (((@ROUND ("End Date",-4) - @ROUND ("Start Date",-4))/10000*12) + 
    ((@ROUND ("End Date",-2) - @ROUND ("End Date",-4))/100)-
    ((@ROUND ("Start Date",-2) - @ROUND ("Start Date",-4))/100))
Utilisation de la fonction @CURRMBR

La fonction @CURRMBR, qui renvoie le nom du membre de dimension en cours de calcul, est particulièrement utile pour définir la portée des calculs complexes et les gérer. Cependant, vous devez prendre en considération son impact sur les performances.

Les performances ne sont pas affectées lorsque vous utilisez la fonction @CURRMBR dans une dimension dispersée car le bloc correspond à un seul membre de dimension dispersée uniquement. Cependant, les performances de cette fonction sont ralenties lorsqu'elle est utilisée dans des dimensions denses car elle exécute des calculs au niveau du bloc et non au niveau de la cellule. Par conséquent, cette fonction calcule tous les membres de dimension dense, même si un membre de dimension dense spécifique n'est pas présent dans la requête. Utilisez donc cette fonction avec parcimonie dans les dimensions denses.

De plus, lorsqu'elle est utilisée dans des dimensions denses, la fonction @CURRMBR peut générer des erreurs ou des résultats inattendus si elle est employée conjointement avec d'autres fonctions telles que @CONCATENATE. Par exemple, si un membre calculé dynamiquement dans une requête contient la formule "Actual"->@MEMBER(@CONCATENATE(@NAME (@CURRMBR ("Account")),"_Total")) et que la dimension de compte est dispersée, la requête est exécutée sans erreur tant que le compte dans la requête génère un membre d'outline valide. Cependant, si la dimension de compte est dense, la requête génère l'erreur suivante même si le compte dans la requête génère un membre d'outline valide.

Erreur lors de l'exécution de la formule pour [nom de membre] (ligne 0) : tentative de franchissement d'un membre @ NULL dans la fonction [@X]

Cette erreur s'est produite car la fonction @CURRMBR effectue le calcul au niveau du bloc et calcule donc tous les comptes du bloc dense. Tous les comptes au sein du bloc ne génèrent pas un membre d'outline valide, ce qui génère le message d'erreur précédent. Pour plus d'informations sur la fonction @CURRMBR, reportez-vous à la section @CURRMBR du guide Référence technique d'Oracle Essbase .

Utilisation du mode bloc et du mode cellule

  • Utiliser le mode bloc, dans lequel les cellules sont regroupées dans le bloc et calculées simultanément, est généralement plus rapide mais les dépendances des données doivent être considérées avec attention. Par exemple, SalesYTD = CurMth + PriorMth doit être calculé en mode cellule pour que chaque mois soit calculé dans l'ordre de l'outline.
  • En mode cellule, chaque cellule est calculée séquentiellement dans l'ordre des dimensions denses dans l'outline. Ce mode est généralement plus lent que le mode bloc.
  • Utilisez @CALCMODE pour contrôler manuellement si le mode bloc ou cellule est utilisé.
  • Utilisez les journaux d'application en mode de débogage pour vérifier le mode de calcul. Si un calcul est exécuté en mode bloc, aucun message ne s'affiche. Un message de journal s'affiche lorsque des calculs sont effectués en mode cellule.

Recommandations pour la création de blocs et la taille des blocs

La taille de bloc recommandée pour des performances optimales est comprise entre 8 ko and 200 ko. Afin de maintenir une taille de bloc BSO optimale, Oracle recommande d'ajouter aux cubes BSO uniquement les comptes utilisés pour la planification et la prévision. Lorsque cela est possible, utilisez des cubes ASO pour la création de rapports en ajoutant tous les comptes de reporting aux cubes ASO. De plus, pour rationaliser la taille du bloc, Oracle recommande que tous les niveaux supérieurs dans les dimensions denses qui sont des agrégations de leurs enfants soient définis sur le type Calcul dynamique (autre que de stockage) ou Information seule.

Les blocs sont généralement créés lors des actions suivantes :

  • Chargement de données
  • DATACOPY
  • Calculs dispersés, par exemple : AGG or SparseMember = X * X/X;

Un calcul dispersé est déclenché dans les cas suivants :

  • Les membres dispersés se trouvent à gauche du signe égal (=).
  • La formule se trouve dans un bloc de membres de calcul dispersé, par exemple : "Budget"("Sales" = "Sales"->"Actual" * 0.95;) en supposant que Scénario est dispersé et que Mesures est dense.

Les blocs peuvent être créés à l'aide des commandes de calcul SET CREATEBLOCKONEQ, SET CREATENONMISSINGBLK ou la fonction de calcul @CREATEBLOCK.

Oracle recommande que ces paramètres soient utilisés avec parcimonie et au sein d'une instruction FIX étroite. Vérifiez si vous pouvez éviter d'utiliser ces instructions en modifiant le type de calcul en cours d'exécution.

Lorsque vous rencontrez un problème, déterminez d'abord s'il est lié à la création de blocs avant d'utiliser ces commandes ou fonctions de calcul. Pour cela, vous pouvez soumettre un zéro (0) dans le bloc cible et réexécuter le calcul.

Lors du développement de règles métier, effacez et rechargez toujours les données (au lieu de soumettre #missing ou d'exécuter un script Clearblock ou ClearData) lorsque vous testez les règles qui peuvent entraîner un problème de création de blocs.

Utilisation de calculs BOTTOMUP et TOPDOWN

  • Ajoutez la fonction de calcul @CALCMODE(BOTTOMUP) ou la commande de calcul SET FRMLBOTTOMUP pour calculer uniquement les blocs existants (BOTTOMUP) au lieu des blocs potentiels (TOPDOWN).
  • Puisque les calculs TOPDOWN calculent tous les blocs de données potentiels avec le membre, enlevez tous les membres non pertinents des dimensions dispersées.
  • Testez minutieusement les calculs à l'aide de BOTTOMUP pour vous assurer que les blocs sont créés correctement lors de l'utilisation de @CALCMODE.
  • Lorsque vous utilisez un calcul BOTTOMUP, testez-le intégralement en effaçant les données et en le réexécutant afin de déterminer si tous les blocs sont créés correctement.
  • Utilisez les journaux d'application en mode de débogage pour vérifier le mode de calcul. Si un calcul est exécuté BOTTOMUP, aucun message ne s'affiche. Un message du journal s'affiche si des calculs sont exécutés TOPDOWN.

Agrégations

  • Une agrégation de dimension dispersée doit être organisée de façon à commencer par la dimension qui crée le moins de blocs jusqu'à celle qui en crée le plus afin de maintenir le nombre de blocs aussi bas que possible, aussi longtemps que possible.
  • N'établissez pas de règles métier d'utilisateur final pour agréger des dimensions dispersées entières.
  • Déplacez uniquement les agrégations requises pour créer un rapport sur le type de plan ASO.
  • Agrégez les données requises uniquement pour le processus d'approbation de la planification.

Utilisation d'AGG au lieu des commandes de calcul CALC DIM

  • CALC DIM exécute toute formule de membre.
  • CALC DIM agrège des dimensions denses ou dispersées.
  • AGG effectue une agrégation en fonction de la structure d'outline.
  • AGG n'exécute pas de formule membre.
  • AGG agrège uniquement des dimensions dispersées.
Testez AGG et CALC DIM car les performances peuvent varier selon le niveau d'agrégation utilisé dans le calcul. Excluez les dimensions avec un calcul dynamique sur les niveaux supérieurs de toutes les agrégations. Agrégez uniquement les données requises.

Utilisation des commandes de calcul SET CALCPARALLEL et FIXPARALLEL

  • Pour les applications multiutilisateurs pouvant exécuter les règles simultanément, exécutez les règles métier en mode série.
  • Utilisez uniquement SET CALCPARALLEL autour des agrégations de dimension dispersée entières dans les calculs par lot.
  • Un calcul parallèle n'est pas recommandé pour les petits scripts, comme les scripts qui sont exécutés pendant moins de 20 secondes, car les frais généraux liés à la création d'un parallélisme peuvent être plus importants que les avantages.
  • Testez toujours la commande de calcul SET CALCPARALLEL pour vous assurer qu'elle est avantageuse. Les calculs en série ou avec des niveaux de parallélisme inférieurs peuvent parfois générer de meilleurs résultats.
  • Effectuez un test pour déterminer si FIXPARALLEL fournit de meilleurs résultats que SET CALCPARALLEL. Utilisez Calculation Manager en mode de débogage pour consulter les journaux.
  • Prenez toujours en compte le nombre d'utilisateurs simultanés lorsque vous employez SET CALCPARALLEL et FIXPARALLEL.

Pour plus d'informations, reportez-vous à la section FIXPARALLEL...ENDFIXPARALLEL dans le guide Référence technique d'Oracle Essbase .

Incidence de l'activation des cubes hybrides sur les calculs dans Planning

Passez en revue les résultats calculés dans les processus métier Planning compatibles avec les cubes hybrides si vous utilisez des constantes, et non des valeurs de données d'autres membres (par exemple, pour Fév, nombre de jour dans le mois = 28), pour affecter des valeurs dans les calculs.

Les résultats de calcul dans les processus métier Planning compatibles avec les cubes hybrides peuvent différer des résultats observés dans les processus métier non compatibles avec les cubes hybrides. Cette différence peut provenir de la configuration utilisée par les processus métier Planning compatibles avec les cubes hybrides, qui ignore toutes les formules reposant uniquement sur des constantes pour affecter une valeur de données. Pour résoudre ce problème, ajoutez @CreateBlock sur un élément dense de la formule. Lorsque @CreateBlock se trouve sur une dimension dense, cet ajout crée les blocs pour tous les autres éléments denses en même temps. Employez également l'instruction ELSE avec toutes les instructions IF afin de vous assurer que tous les blocs requis ont été créés.

Pour plus d'informations sur l'utilisateur d'Essbase dans Oracle Enterprise Performance Management Cloud, reportez-vous à la section "A propos d'Essbase dans EPM Cloud" dans le guide Mise en route d'Oracle Enterprise Performance Management Cloud pour les administrateurs.