Problème de performance sur dashboard avec beaucoup de graphiques

Edit: J’ai changé le titre de ce message vu qu’au final il s’agissait d’un problème de performance propre à Gladys.

Bonjour :slight_smile:

Il ne s’agit pas vraiment d’une fonctionnalité domotique à proprement parler et c’est quelque chose qui demande un gros dev ^^

Mais je pense qu’il pourrait être utile d’avoir le choix lors de l’installation de Gladys si on souhaite avoir une base SQLite ou MySQL.

Pourquoi ce besoin ?
Lorsque l’on commence à avoir beaucoup de modules sur un dashbord notamment des graphiques, SQLite montrent ces limites (environ 10sec pour afficher mon dashbord principal)

Une base MySQL permettra de rendre plus performant Gladys lors de multiples requêtes en // et améliorer la fluidité des dashbords.

Il ne s’agit là que de mon avis ^^

Mon avis : Si à l’installation tu me demandes de choisir, je n’installe pas car je ne comprends pas et je me dis que ça n’est pas pour moi :innocent:
Cela dit, j’imagine que le choix technique qui a été posé est/a été réfléchi (et peut sûrement évoluer en cas de besoin :wink: )

Je suis effectivement d’accord que ce genre de choix perdrait une grande partie des utilisateurs et que SQLite est suffisant pour la grande majorité des installations.

Après ce choix peut se trouver dans un onglet « configuration avancée » par exemple qui serait opérationnel.

Mais c’est sûr que c’est un gros dev pour je pense une minorité d’utilisateur

1 Like

Salut @Checconio !

Je ne pense pas que MySQL soit la solution a ton problème. SQLite est tout aussi performant pour cet usage, ce n’est pas parce qu’il y a « Lite » dans le nom de que c’est plus lent, au contraire :smiley:

Il faut plutôt résoudre ce souci de performance dans Gladys :slight_smile:

Est-ce que ça te dérangerait de me fournir ta DB (en privée) pour que je fasse des tests de performances de mon côté ?

Quelle est la vitesse de ton disque ?

Pour mesurer la vitesse, je te conseille de suivre ce tuto => Your Web Host Doesn’t Want You To Read This: Benchmark Your VPS, avec la commande dd tu pourras mesurer la performance en écriture/puis lecture.

Merci pour ce retour @pierre-gilles

Je sais que SQLite est très performant chaque gestionnaire de BDD a ses points faibles et forts, c’est pour cette raison que le sujet reste une proposition :slight_smile:
Tu reste le mieux placer pour connaitre le fonctionnement de Gladys avec la BDD

Aucun problème pour aider à l’optimisation !

Gladys est sur SSD M2, vitesse après benchmark écriture: entre 350 et 380 Mo/s
Côté processeur: 2,7 Ghz 4 coeur
Ram: 8 Go + 1Go swap

Je t’envoi ma BDD en privé

1 Like

Merci @Checconio pour la DB que tu m’as envoyé en privée, j’ai pu effectuer un petit audit de performance sur tes données et ça m’a beaucoup aidé, j’ai trouvé le souci ! :slight_smile:

Déjà, le souci était très clair, c’était hyper lent même sur ma machine de développement qui est assez puissante, je sais pas comment tu fais pour supporter ça c’était ultra lent ^^

Pour imager, je voyais ça:

Quasi 40 secondes pour afficher la page, c’est juste énorme ^^

J’ai passé Gladys localement en mode debug pour voir les requêtes SQL exécutés et je suis allé les jouer manuellement sur la DB, « en direct ».

6 secondes pour une requête qui renvoie rien, c’est beaucoup !

J’ai donc tiré la pelote, il y a 2 conditions sur cette query (WHERE device_feature_id = ? AND created_at >= ?), et ces deux attributs ont bien un index…

J’exécute EXPLAIN QUERY PLAN pour comprendre ce que fait SQLite, et je comprends.

SQLite pouvait utiliser l’index sur device_feature_id pour aller chercher tous les états de cette fonctionnalité, mais ensuite il faisait un scan sequentiel pour aller filtrer par date: l’index sur date n’était pas utilisé.

La solution est tout simple, il suffit d’ajouter un index qui couvre les 2 attributs utilisés lors de la requête.

J’ai donc rajouté 2 index sur device_feature_state et t_device_feature_state_aggregate couvrant les attributs utilisés lors des requêtes du tableau de bord.

await queryInterface.addIndex('t_device_feature_state', ['device_feature_id', 'created_at']);
await queryInterface.addIndex('t_device_feature_state_aggregate', ['device_feature_id', 'type', 'created_at']);

Et là: bam! Cette même requête passe de 6 secondes à… 5ms !! :grimacing:

Sur la totalité de la page, on passe de 40 secondes à… 100 ms sur ma machine !

Je te l’avais dis, c’était pas du à SQlite, on aurait eu le même soucis sur MySQL :wink:

J’ai fais une PR qui corrige le souci, ça partira dans la prochaine version de Gladys:

@Terdious @lmilcent ça va vous intéresser vous qui avez beaucoup de data !

6 Likes

C’est super !

Et merci pour les explications :smiley:
Cette grosse optimisation me permettra de continuer à faire gonfler mon Gladys correctement :wink:

2 Likes

Oh oui j’ai hâte de tester et valider que ça change tout chez moi :slight_smile:

1 Like

Pierre Gilles, premier défenseur de SQlite :shield: Merci pour l’analyse et la correction, très intéressantes.

2 Likes

J’ai un build sur le tag dev en cours, je vous tiens au courant quand c’est prêt :wink:

Dans notre cas d’usage (programme embarqué), SQLite est le plus adapté, c’est pour ça que je le défend :smiley: Des SGBD client/serveur (MySQL/PostgreSQL) sont adaptés lorsqu’on a un serveur de base de donnée qui est consulté par plusieurs clients en réseau.

Je cite le site de Sqlite: Appropriate Uses For SQLite

2 Likes

Le build est prêt:

Après 26 minutes de mise à jour de ma base de donnée suite à ton patch, je confirme l’énorme gain en rapidité sur les dashboards.

Je peux charger en boucle tous les dashboards en instantanné ou presque. Auparavant je faisais « planter » Gladys 5 à 10 secondes sur mes dashboards avec beaucoup de graphiques.

1 Like

Génial ! Yes c’est normal que la migration prenne du temps, il faut construire tout l’index.

Ta base de donnée sera aussi plus grosse, facile +20% normalement mais c’est le prix à payer pour que ça soit instantanée à afficher ! :smile:

Ah oui, de 6.3Go à 7.9Go :scream:

1 Like

Ouai mais tu va pouvoir virer des features de l’historique ça fera un peu de place :grin:

2 Likes

Clairement.
J’avoue que j’ose pas encore y toucher, quelqu’un l’a déjà fait ?

Moi je le faisais en db :sunglasses:

2 Likes

@euguuu a testé et ça marche !

Le bonus c’est qu’à chaque fois que tu retire des features de l’historique, Gladys fait tourner un petit VACUUM donc ça fait du nettoyage aussi :wink:

1 Like

Woaw merci pour le lien, j’étais passé à côté. Je suis impatient de tester ça !!

1 Like

@pierre-gilles, j’ai essayé hier soir d’installer Gladys sur mon PC fixe, d’utiliser ma DB actuelle pour ensuite supprimer des features.
Mon PC fixe utilise un SSD NVME donc ça doit être super rapide, bien plus que mon RPi qui prend 10h pour traiter les 8Go de ma DB et supprimer les features…

MAIS, comme le service Zigbee2MQTT doit être utilisé et qu’il n’est pas lancé dans l’instance de dev que j’ai installé sur mon PC, impossible d’accéder aux périphériques pour supprimer les features.

→ As tu une astuce pour me permettre de réaliser la suppression des features sur mon PC fixe et ensuite réutiliser cette version de DB modifiée sur mon RPi ?