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.
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.
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.
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.
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…