|
MVP - lenteur récupération des donées |
Started by Eric D, Dec., 09 2016 3:18 PM - 7 replies |
| |
| | | |
|
| |
Posted on December, 09 2016 - 3:18 PM |
Bonjour,
je développe un petit ERP avec windev 20, relié à un base HFSQl Client/Serveur d'environ 750 mo, en utilisant le design pattern MVP.
Je me suis appuyées sur l'exemple fournit par PCSoft : "Découverte MVP - Partie 2" pour mon développement. Ainsi mes classe models sont mappées à leur table respective et elles héritent d'une classe Base s'occupant de l’enregistrement et de la récupération des données avec les fonctions FichierVersMémoire() et MémoireVersFichier().
Malgré ce principe d'accès aux données qui me semble correcte, la récupération est très longue.
Est-ce que l'un d'entre vous a déjà eu un problème de ce genre avec ce principe ou avec le MVP ? Est-ce que ça peut-être HFSQL ou mon serveur qui ne sont pas assez puissant ?
Merci de vos retours. Cordialement |
| |
| |
| | | |
|
| | |
| |
Posted on December, 09 2016 - 7:48 PM |
Bonjour
je n'utilise pas ce modèle, mais je peux te dire que le problème ne vient pas de la base.
Le simple fait que tu nous dise que "...la récupération est très longue..." sans autre précisions montre que tu ne maitrise pas la logique d'accès à une base de données. MVP ou pas n'a rien à y voir non plus.
Quelle récupération ? Sur une requête ? Sur un code particulier ? Pour remplir une table ? C'est combien "très longue" ? Pour combien d'enreg ?
Cordialement
-- Fabrice Harari Consultant WinDev, WebDev et WinDev Mobile International
A votre disposition : WXShowroom.com, WXReplication (open source) et maintenant WXEDM (open source)
Plus d'information sur http://fabriceharari.com
Le 12/9/2016 à 9:18 AM, Eric D a écrit :
Bonjour,
je développe un petit ERP avec windev 20, relié à un base HFSQl Client/Serveur d'environ 750 mo, en utilisant le design pattern MVP.
Je me suis appuyées sur l'exemple fournit par PCSoft : "Découverte MVP - Partie 2" pour mon développement. Ainsi mes classe models sont mappées à leur table respective et elles héritent d'une classe Base s'occupant de l’enregistrement et de la récupération des données avec les fonctions FichierVersMémoire() et MémoireVersFichier().
Malgré ce principe d'accès aux données qui me semble correcte, la récupération est très longue.
Est-ce que l'un d'entre vous a déjà eu un problème de ce genre avec ce principe ou avec le MVP ? Est-ce que ça peut-être HFSQL ou mon serveur qui ne sont pas assez puissant ?
Merci de vos retours. Cordialement |
| |
| |
| | | |
|
| | |
| |
Posted on December, 12 2016 - 11:12 AM |
Bonjour,
merci de votre retour.
Je l'admets l'explication n'est pas claire.
Je suis en train de créer une fenêtre avec un tableau, ou l'on peut ajouter / modifier / supprimer une ligne (classique). Les données sont récupérées grâce à une boucle "POUR TOUT <nom de la table>" ou grâce aux fonctions "HLit...". Chaque enregistrement lu crée un objet qui est remplit grâce à la fonction "FichierVersMémoire()" (Les attributs de mes classes étant mappés à leurs attributs de la base), et qui fait la même chose pour les classes associées.
Ainsi mon tableau affiche environ 7000 lignes en 2 minutes. Les données sont pris sur 7 tables différentes, ou l'on prend au plus 7000 enregistrements sur chacune, pour un poids théorique de 18 mo.
Je précise que je débute en WinDev et que c'est la première fois que je développe avec une base ayant plusieurs millier d'enregistrements (Où sont les cas d'école avec une dizaine d’enregistrements ???)
Cordialement. |
| |
| |
| | | |
|
| | |
| |
Posted on December, 12 2016 - 1:52 PM |
Bonjour
ce n'est pas un problème lié à windev, c'est un problème de conception de l'appli.
D'abord, afficher une table avec 7000 lignes dedans, en 30 ans de développement, je n'ai JAMAIS vu un cas ou c'était nécessaire ou utile.
PERSONNE ne va lire 7000 lignes.
Donc, il faut afficher une table vide, avec des champs de recherche/sélection au dessus, et n'afficher que ce que l'utilisateur veut vraiment voir...
Ensuite, pour ce genre de chose, il faut privilégier des requêtes pour limiter le nombre de transferts par le réseau.
Enfin, il faut bloquer l'affichage (..affichageactif, de mémoire) pendant le remplissage de la table et le réactiver une fois qu'elle est pleine.
Quand à dire que c'est très lent, relativisons : tu nous dis que tu lis et affiche 49 000 enregs au total (7000*7), en 120 secondes. Ca fait pas loin de 410 enregs lus par seconde. C'est loin d'être lent. Ca peut être optimisé grace aux méthodes décrites au dessus, mais c'est loin d'être lent vu les méthodes utilisées pour l'instant.
Cordialement
-- Fabrice Harari Consultant WinDev, WebDev et WinDev Mobile International
A votre disposition : WXShowroom.com, WXReplication (open source) et maintenant WXEDM (open source)
Plus d'information sur http://fabriceharari.com
Le 12/12/2016 à 5:12 AM, Eric D a écrit :
Bonjour,
merci de votre retour.
Je l'admets l'explication n'est pas claire.
Je suis en train de créer une fenêtre avec un tableau, ou l'on peut ajouter / modifier / supprimer une ligne (classique). Les données sont récupérées grâce à une boucle "POUR TOUT <nom de la table>" ou grâce aux fonctions "HLit...". Chaque enregistrement lu crée un objet qui est remplit grâce à la fonction "FichierVersMémoire()" (Les attributs de mes classes étant mappés à leurs attributs de la base), et qui fait la même chose pour les classes associées.
Ainsi mon tableau affiche environ 7000 lignes en 2 minutes. Les données sont pris sur 7 tables différentes, ou l'on prend au plus 7000 enregistrements sur chacune, pour un poids théorique de 18 mo.
Je précise que je débute en WinDev et que c'est la première fois que je développe avec une base ayant plusieurs millier d'enregistrements (Où sont les cas d'école avec une dizaine d’enregistrements ???)
Cordialement. |
| |
| |
| | | |
|
| | |
| |
Posted on December, 12 2016 - 4:46 PM |
Il y a un outil : l'analyseur de performance. En utilisant cet outil, tu sauras précisément combien de fois chaque fonction a été exécutée, combien de temps elle a pris etc etc, et tu pourras mieux cibler ton problème. Cet outil est essentiel en cas de problèmes de performance.
L'autre piste, c'est de passer par un hReIndexe() Il faut lancer cette commande à intervalle réguliers. Un bon hReindexe() avec les bons paramètres, et les temps de réponse peuvent être divisés par 5 voire plus. |
| |
| |
| | | |
|
| | |
| |
Registered member 90 messages Popularité : +7 (11 votes) |
|
Posted on December, 13 2016 - 9:30 AM |
Fabrice Harari a écrit :
Bonjour
ce n'est pas un problème lié à windev, c'est un problème de conception de l'appli.
D'abord, afficher une table avec 7000 lignes dedans, en 30 ans de développement, je n'ai JAMAIS vu un cas ou c'était nécessaire ou utile.
PERSONNE ne va lire 7000 lignes.
Les lire, non. Mais sa table peut être utile ensuite pour de l'export, pour des stats ou que sais-je d'autres... Ce n'est pas l'aider que de lui dire de ne pas faire ça.
déjà le ..affichageactif = faux avant le traitement devrait améliorer les choses. Ensuite, passer par une requête. Eviter aussi les traitements sur affichage d'une ligne...
Il y a peut-être des données qui peuvent être récupérées avant et stocker dans des tableaux de structure. et donc éviter les accès base à ce moment là.
voir aussi les index.
Bref il y a plein de piste, mais sans code, ni même de contexte, difficile de t'aider. |
| |
| |
| | | |
|
| | |
| |
Registered member 2 messages |
|
Posted on December, 13 2016 - 11:39 AM |
Merci pour vos conseils, je vais y regarder de plus près.
Le contexte étant que je souhaite afficher la liste des recoupes avec pour chacune sa cause avec sa famille, l'employé la demandant, le numéro du bon de fabrication et de la série, ainsi que l'article avec sa matière et sa couleur.
Pour le code, je suis en train de tous refaire, l'analyseur de Performance montre que ça ne viens pas de la base de données, mais je vous mets la classe Base, s'occupant de la récupération et de l'enregistrement des données.
Base est une Classe nouveau est un booléen
PRIVÉE id est un Variant nomTable est une chaîne nomClePrimaine est une chaîne FIN
Procedure Constructeur(snomTable, snomClePrimaine)
nouveau=Vrai
nomTable=snomTable nomClePrimaine=snomClePrimaine
Procedure Enregistrer(lErreur est une CErreur)
SI nouveau ALORS HRAZ(MonFichierMappé) MémoireVersFichier(objet,MonFichierMappé) HAjoute(MonFichierMappé) SI ErreurDétectée() ALORS lErreur.Initialise(CErreur::ErreurHFSQL,HErreurInfo()) id = {nomTable+"."+nomClePrimaine, indRubrique} FichierVersMémoire(objet,MonFichierMappé) nouveau=Faux
SINON HLitRecherchePremier(MonFichierMappé,MaCléUniqueMappée,id) SI HTrouve() ALORS MémoireVersFichier(objet,MonFichierMappé) HModifie(MonFichierMappé) SI ErreurDétectée() ALORS lErreur.Initialise(CErreur::ErreurHFSQL,HErreurInfo()) SINON lErreur.Initialise(CErreur::NonTrouvé) FIN FIN
RENVOYER lErreur.ok
Procedure Supprimer(lErreur est un CErreur)
SI nouveau ALORS RENVOYER Vrai
HLitRecherchePremier(MonFichierMappé,MaCléUniqueMappée,id) SI HTrouve() ALORS HSupprime(MonFichierMappé) SI ErreurDétectée() ALORS lErreur.Initialise(CErreur::ErreurHFSQL,HErreurInfo()) SINON lErreur.Initialise(CErreur::NonTrouvé) FIN
RENVOYER lErreur.ok
Procedure Charger(Source est une chaîne = "")
nouveau = Faux
SI Source = "" ALORS id = {nomTable+"."+nomClePrimaine, indRubrique}
FichierVersMémoire(objet,MonFichierMappé) SINON id = {Source+"."+nomClePrimaine, indRubrique} FichierVersMémoire(objet,Source) FIN
Ci-dessous le bout du MPD utiliser pour cette fenêtre.
Je précise que je reprends un ERP développé par une personne qui n’était pas un développeur, quelle avait déjà créer une fenêtre listant les recoupes comme voulus, où les données était toutes dans la même table (Je vous dis pas le nombre de doublons dans la base), et donc le tableau était relier à la table recoupe pour un affichage en quelques secondes. |
| |
| |
| | | |
|
| | |
| |
Posted on April, 06 2017 - 1:13 AM |
Coucou,
Utilse plutot "clé unique" que
id = {Source+"."+nomClePrimaine, indRubrique}
MServer est une Classe, mapping=Server hérite de MBase PRIVÉE
m_n8ID est un entier sur 8 octets <mapping=IDServer, clé unique> FIN
MBase est une Classe FIN
Procedure PUBLIQUE ID(): entier sur 8 octets
ErreurChangeParamètre(epGotoCasErreur) ExceptionChangeParamètre(epGotoCasException) RENVOYER {"m_n8ID", indVariable} CAS ERREUR: ErreurPropage() RENVOYER -1 CAS EXCEPTION: ExceptionPropage() RENVOYER -1
Charly |
| |
| |
| | | |
|
| | | | |
| | |
|