PC SOFT

FORUMS PROFESSIONNELS
WINDEVWEBDEV et WINDEV Mobile

Accueil → WINDEV 2024 → Optimiser un traitement trop long
Optimiser un traitement trop long
Débuté par Lucie, 03 nov. 2006 10:56 - 6 réponses
Posté le 03 novembre 2006 - 10:56
Bonjour,

Je souhaiterais optimiser - si c'est possible - un traitement qui est actuellement beaucoup trop long.

Ce traitement lit l'ensemble de enregistrements d'un fichier (d'une requête).
Pour chaque enregistrement trouvé, il recherche son existence dans un autre fichier : s'il existe déjà, il le met à jour, sinon il le crée.

En voici le code simplifié:

HExécuteRequête(mareq1,hRequêteDéfaut,param1,param2)
HLitPremier(mareq1)
TANTQUE PAS HEnDehors(mareq1)

//========================================
// Recherche existence enreg.
//========================================
SI PAS HExécuteRequête(mareq2, hRequêteDéfaut+hModifieFichier, param3, param4, param5 ,param6) ALORS
Erreur("Erreur d'initialisation de la requête"+RC+HErreurInfo())
RETOUR
FIN

HLitPremier(mareq2)
//========================================
// si enreg trouvé, màj
//=========================================
SI PAS HEnDehors(mareq2)
//Alim des rubriques de mareq2
.....
HModifie(mareq2)
SINON
//========================================
// si enreg pas trouvé, création
//=========================================
// Alim des rubriques du fichier Fich1
...
HAjoute(Fich1)
FIN
HAnnuleDéclaration(mareq2)

HLitSuivant(mareq1)
FIN

HAnnuleDéclaration(mareq1)


Informations complémentaires :

- Application en HF/CS
- nb enreg. de mareq1 = 3000
- la boucle sur mareq1 SANS le traitement de recherche existence enreg. prend 1 à 2 secondes.
- la boucle sur mareq1 AVEC le traitement de recherche existence enreg. prend 3 à 4 MINUTES !!!
- les requêtes sont optimisées.

Le problème vient-il du nombre de paramètres que je passe à mareq2 ?
J'utilise des requêtes car je suis en C/S.

Je ne sais vraiment pas comment optimiser ce traitement pourtant tout simple ...

Merci par avance pour toute suggestion.

Lucie
Posté le 03 novembre 2006 - 11:52
Bonjour,
Tu peux déjà utiliser l'analyseur de performance, pour savoir quelles lignes de code prennent le plus de temps (à mon avis SI PAS HExécuteRequête(mareq2, hRequêteDéfaut+hModifieFichier, param3, param4, param5 ,param6) ALORS).
Ensuite, il faut vérifier si la deuxième requête utilisent bien des indexes.

Tu peux aussi modifier ton code, et faire une requête du genre:
select f1.champ1,fic1.champ2... ,fic2.champ1 from fic1 left outer join fic2 on fic1.jointure1 = fic2.jointure2

De cette façon, si fic2.champ1 est non null un enregistrement est trouvé, sinon aucun enregistrement trouvé. Tu remplaces alors 3001 requêtes par une seule requête.

Frédéric.
Posté le 03 novembre 2006 - 11:52
Bonjour,
Via l'optimiseur de performance lance le traitement et regarde ce qui prend le plus de temps.

Pour optimiser les traitements tu peux aussi sur les requêtes : Ne ramener que les champs nécessaires à la modification ou à l'ajout.

Tu fais des ajouts dans un fichier -> + long car création de l'index en parallèle.

Tu peux aussi mettre ce bout de code (Tu évites une lecture de la requête .... je suis sceptique sur le gain de temps mais bon on optimise ...)

Si HNbEnr(mareq2) <> 0 alors
HLitPremier(mareq2)
//========================================
// si enreg trouvé, màj
//=========================================
SI PAS HEnDehors(mareq2)
//Alim des rubriques de mareq2
.....
HModifie(mareq2)
FIN
SINON // la requête n'a rien ramené
//========================================
// si enreg pas trouvé, création
//=========================================
// Alim des rubriques du fichier Fich1
...
HAjoute(Fich1)
FIN
HAnnuleDéclaration(mareq2)

HLitSuivant(mareq1)
FIN



Si tu arrives à gagner du temps indique-moi ta méthode et préviens-moi, je connais aussi ce genre de "problème".

Michel.

PS : pour un traitement "long" avec de nombreux ajouts j'ai optimisé les ajouts via la fonction Hécrit() avec réindexation au final ! Cela n'est pas possible si multi-users sur le fichier !!!
Posté le 03 novembre 2006 - 11:52
Quelques pistes, en vrac :
- remplacer les HLitPremier/HLitSuivant par un POUR TOUT
- pour faire un test, c'est peut etre le hModifierFichier dans
l'exécution de mareq2 qui ralentit le traitement ?
- mais je pense que le soucis majeur est que tu exécutes mareq2 3000
fois (vu le nombre d'enregistrement dans mareq1)...

voilà :)
bon dev
eric l.

> Lucie a écrit :
Bonjour,

Je souhaiterais optimiser - si c'est possible - un traitement qui est actuellement beaucoup trop long.

Ce traitement lit l'ensemble de enregistrements d'un fichier (d'une requête).
Pour chaque enregistrement trouvé, il recherche son existence dans un autre fichier : s'il existe déjà, il le met à jour, sinon il le crée.

En voici le code simplifié:

HExécuteRequête(mareq1,hRequêteDéfaut,param1,param2)
HLitPremier(mareq1)
TANTQUE PAS HEnDehors(mareq1)

//========================================
// Recherche existence enreg.
//========================================
SI PAS HExécuteRequête(mareq2, hRequêteDéfaut+hModifieFichier, param3, param4, param5 ,param6) ALORS
Erreur("Erreur d'initialisation de la requête"+RC+HErreurInfo())
RETOUR
FIN

HLitPremier(mareq2)
//========================================
// si enreg trouvé, màj
//=========================================
SI PAS HEnDehors(mareq2)
//Alim des rubriques de mareq2
.....
HModifie(mareq2)
SINON
//========================================
// si enreg pas trouvé, création
//=========================================
// Alim des rubriques du fichier Fich1
...
HAjoute(Fich1)
FIN
HAnnuleDéclaration(mareq2)

HLitSuivant(mareq1)
FIN

HAnnuleDéclaration(mareq1)


Informations complémentaires :

- Application en HF/CS
- nb enreg. de mareq1 = 3000
- la boucle sur mareq1 SANS le traitement de recherche existence enreg. prend 1 à 2 secondes.
- la boucle sur mareq1 AVEC le traitement de recherche existence enreg. prend 3 à 4 MINUTES !!!
- les requêtes sont optimisées.

Le problème vient-il du nombre de paramètres que je passe à mareq2 ?
J'utilise des requêtes car je suis en C/S.

Je ne sais vraiment pas comment optimiser ce traitement pourtant tout simple ...

Merci par avance pour toute suggestion.

Lucie
Posté le 03 novembre 2006 - 12:05
Merci pour toutes ces idées.

Je vais tester et évaluer et vous tenir au courant.

Est-ce que la requête reste quand même, sauf cas particulier (ici ?), "l'outil" le plus rapide pour accéder à un ou plusieurs enregistrements d'un fichier sur un serveur HF ?

Lucie
Posté le 03 novembre 2006 - 15:41
Il faudrait tout d'abord utiliser l'analyseur de performances pour savoir à
quel endroit du code c'est lent
Menu Projet/Performances et Améliroations/Analyser les performances.

bon dev
Posté le 08 novembre 2006 - 19:47
Oui la requête reste toujour l'outil performant pour tout accès à une BDD. Mais ses utilisations ici, font toujours appel à des boucles (en plus la boucle parcours 3000 records) qui rendent la performance médiocre. Ce n'est pas du tout la requête qui cause cette lenteur. Ce sont les boucles utilisées. Pour rendre plus performant la routine, moi je pense qu'il faut utiliser deux vues. Puis avec une troisième vue de disjonction (?? à vérifier), l'on ne boucle que sur quelques enregistrements de décalage pour l'ajout et la mise à jour.
L'idée préconisée précédemment sur l'utilisation d'une requête à jointure externe me parait aussi bonne.
Je suis sûr qu'ainsi, l'appli gagne 1000 fois de performance.