Optimisation performances BDD / création des indexes sur les objets métier

Simplicité 5.1.52

Bonjour,

Nous sommes en production et nous cherchons à optimiser les performances BDD de l’application.

Dans un premier atelier avec Alistair, nous avons identifié un premier axe d’amélioration qui consistait à supprimer tous les champs calculés qui permettrait de réduire considérablement le nombre de requêtes mais au prix d’un refactoring assez conséquent.

On se posait également la question des index BDD; De ce que j’ai compris, simplicité à son propre système d’indexation pour la recherche. Est-ce pertinent de rajouter des index BDD en plus ?

Autre question, est-il possible de désactiver le count/requêtes automatiques sur les panels fils de sorte à ne faire les count/select qu’au clic sur le panel fils ?

Nous somme conscients que cela ne remplacera pas un refactoring sur les champs calculés, mais nous cherchons à obtenir des gains de performance à très court terme dans un premier temps.

Merci d’avance pour votre réponse.

Bonjour,

Question très générale d’optimisation en fonction des volumétries et des usages qui n’a pas de réponse absolue :

Sur les indexes, Simplicité génère :

  • des indexes uniques sur les clés fonctionnelles des objets
  • des indexes non uniques sur les clés étrangères / jointure
  • et propose des indexes sur les autres champs en recherche UI (donc il faut éviter de proposer des recherches sur trop de champs non indexés si la table est importante / fullscan, ou obliger à en saisir certains filtres avec des champs en recherche semi-obligatoire)

Vous pouvez ajouter d’autres indexes que ceux proposés en analysant les requêtes longues / cf le tableau du top 10 de l’onglet “data” du monitoring. Sinon il vous faut des outils d’analyse en BD via un DBA.

Sur les champs calculés :

  • il est toujours plus performant de calculer 1 fois une donnée persistante (au create/save/delete ponctuels) qu’à chaque lecture par N utilisateurs * N fois par jour,
  • S’il y trop de cas de calcul (la donnée calculée dépend de 25 objets modifiables), le calcul global peut être fait par une tache/action Cron périodique qui fera des update/sql en masse (et si la fraicheur de la donnée calculée en temps réel n’est pas nécessaire),
  • si la donnée dépend de vraies variables, ce n’est pas possible de la pré-cacluler (un taux de change, la météo du jour…), dans ce cas il faut calculer/afficher la donnée que dans certains cas (en formulaire uniquement, via une action utilisateur, dans une vue dédiée…) et pas partout (en liste non paginée).

Le count des onglets / listes filles : c’est justement pour éviter à l’utilisateur de cliquer sur tous les onglets pour savoir s’ils contiennent quelque chose. Les count ne sont pas couteux dès lors que les FK sont bien indexées (à vérifier si les requêtes count vues du navigateur/xhr sont longues).

Donc dans un premier temps, vérifiez les requêtes longues s’il y en a, ajoutez des indexes au besoin, et limiter leur quantité (le conseil d’Alistair). Au-delà il faudrait revoir le design de vos écrans / impact fonctionnel/utilisateur encore plus problématique que de changer l’implémentation des champs calculés les plus utilisés dans vos écrans.

Pour regénérer les indexes standards suite à un import de module, vous pouvez passer par la UI :

  • liste des objets métiers filtrée sur votre module
  • menu plus / action “Index proposal” :

Cette action resynchronise les indexes (drop de la clé unique et rebuild…) et en propose en fonction du paramétrage :

Merci pour votre réponse complète.

En ce qui concerne le rechargement des index Simplicité, y-a-t-il un intérêt à le lancer une fois en production dans la mesure ou on a lancé cette action après avoir migré les données dans l’application. Avec la construction des indexes au fur et à mesure, ils devraient toujours être à jour? D’autant plus qu’on ne prévoit pas d’ajouter d’index supplémentaires.

Bonjour,

Je pense que vous parlez des indexes des données de la table m_index pour les recherches full-text
(via le menu Operation > Index > Rebuild). Ceux ci n’optimisent pas les accès SQL (filtre sur les colonnes, jointures…).

Il est également obligatoire de lancer l’action de création d’index physique depuis la liste des objets de votre module pour faire les “CREATE INDEX” (via le menu Admin > Object > Index proposal).

Si vous changez une clé fonctionnelle, ou des jointures… il est important de le faire après une (re)livraison de module(s).

On est en train d’étudier pour le faire automatiquement à la fin d’un import de module.

Ah, on avait pas connaissance de cette création d’indexe.

Comment cela fonctionne ? Au clic sur “Index proposal” cela lance une tache asynchrone qui créé les index ?

L’action semble longue et abouti a une erreur de notre load balancer qui génère une erreur 504. L’action continue bien de tourner en fond ?

Erratum : je viens de tester en local, j’ai le script généré, je vais voir pour le passer sur les autres environnements.

Oui l’erreur Front est liée à un timeout de votre requête, mais le thread en back de la session tourne toujours. Vous devriez avoir de meilleurs performances si cela n’avait pas été fait.

Le libellé de l’action est historique/confusant car fut un temps, Simplicité ne faisait que les proposer au designer qui se chargeait d’en faire ensuite un script SQL à passer dans les différents environnements par les DBA. Mais comme les usages ont changé, on oublie souvent de le faire, donc cette action a fini par les créer/forcer en plus de les proposer.

Votre ticket passe en feature request pour améliorer cette action :

  • Changer son libellé “Générer les indexes”
  • Ajouter un écran de confirmation pour choisir entre générer le script seul ou l’appliquer en base
  • Si on choisit de les appliquer, ça lancera un job asynchrone pour éviter le timeout front / l’action en elle-même restera synchrone pour remonter le script. Il va falloir splitter les 2 car le code fait tout en même temps.

Et au niveau de l’import de module :

  • A la fin si tout est OK, il générera les indexes de base (UK et FK) automatiquement sur tous les objets du module
  • Cette tache regénère également les index full-text, il faut également les resynchroniser de temps en temps car il peut potentiellement y avoir des erreurs, des mises à jour en dur par SQL…

Merci pour ces précisions.

Une fois que ces index sont créés, il faut lancer un REINDEX table sur chaque table quand même j’imagine ?

Non l’action de génération CREATE INDEX sur un objet lance également l’action de recalcul des index full-text.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.