Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

[WD9] Problemes de lenteur

11 réponses
Avatar
serviroc
Bonjour,

J'ai pas mal de souci de lenteur sur mon système de gestion commerciale et
j'aimerais en trouver la cause.
J'ai une application en réseau WD9 avec base de données Hyperfile
Client/Server sur un Compaq Proliant ML350 avec BiProcesseur PIII 1.2Ghz et
1.2 Go De RAM.
J'ouvre un ma connexion au serveur hyperfile au démarrage de l'application !
Environ 20 personnes travaillent en simultanées.
Voici un exemple de mon code qui dure assez longtemp (une vingtaine de
secondes) :

J'accede a deux fichiers COMMANDE_CLIENT(75000 enregistrements),
ELEMENT_COMMANDE(150000 enregistrements).
Il me faut les commandes du client dont je passe le numéro en parametre ->
Num_client dans COMMANDE_CLIENT
Il me faut ensuite pour ces commandes, seulement celles ayant un element
expédiés entre les dates indiquées -> DATE_EXP dans ELEMENT_COMMANDE

reqCde = "SELECT COMMANDE_CLIENT.FACTAVOIR,COMMANDE_CLIENT.FORFAIT,
ELEMENT_COMMANDE.PXVENTE, ELEMENT_COMMANDE.DATE_EXP FROM COMMANDE_CLIENT,
ELEMENT_COMMANDE WHERE COMMANDE_CLIENT.NUM_CDE=ELEMENT_COMMANDE.NUM_CDE AND
COMMANDE_CLIENT.NUM_CLIENT='" + numéroclient + "' AND DATE_EXP BETWEEN '" +
DateDepart + "' AND '" + DateFin +"'"
Si HExécuteRequêteSQL(SrcCde,reqCde) alors
HLitPremier(SrcCde)
TANTQUE PAS Hendehors(SrcCde)

... <Suite du code>

HLitSuivant(SrcCde)
FIN
FIN

Comment puis-je faire pour optimiser ce code ?



Cordialement !


Serviroc

10 réponses

1 2
Avatar
JPN
Tu n'as pas essayé en passant par un hfiltre ?
je sais que ce n'est pas top, mais dans mon appli, les requetes étaient
d'une lenteur déconcertante et depuis qu'on est repassé par des ordre wd
classiques, on a retrouvé un peu de vitesse. bizarre, mais je n'ai pas pris
le temps de chercher la raison.

Jeanphi

"serviroc" a écrit dans le message de news:
424a773a$0$25055$
Bonjour,

J'ai pas mal de souci de lenteur sur mon système de gestion commerciale et
j'aimerais en trouver la cause.
J'ai une application en réseau WD9 avec base de données Hyperfile
Client/Server sur un Compaq Proliant ML350 avec BiProcesseur PIII 1.2Ghz


et
1.2 Go De RAM.
J'ouvre un ma connexion au serveur hyperfile au démarrage de l'application


!
Environ 20 personnes travaillent en simultanées.
Voici un exemple de mon code qui dure assez longtemp (une vingtaine de
secondes) :

J'accede a deux fichiers COMMANDE_CLIENT(75000 enregistrements),
ELEMENT_COMMANDE(150000 enregistrements).
Il me faut les commandes du client dont je passe le numéro en parametre ->
Num_client dans COMMANDE_CLIENT
Il me faut ensuite pour ces commandes, seulement celles ayant un element
expédiés entre les dates indiquées -> DATE_EXP dans ELEMENT_COMMANDE

reqCde = "SELECT COMMANDE_CLIENT.FACTAVOIR,COMMANDE_CLIENT.FORFAIT,
ELEMENT_COMMANDE.PXVENTE, ELEMENT_COMMANDE.DATE_EXP FROM COMMANDE_CLIENT,
ELEMENT_COMMANDE WHERE COMMANDE_CLIENT.NUM_CDE=ELEMENT_COMMANDE.NUM_CDE


AND
COMMANDE_CLIENT.NUM_CLIENT='" + numéroclient + "' AND DATE_EXP BETWEEN '"


+
DateDepart + "' AND '" + DateFin +"'"
Si HExécuteRequêteSQL(SrcCde,reqCde) alors
HLitPremier(SrcCde)
TANTQUE PAS Hendehors(SrcCde)

... <Suite du code>

HLitSuivant(SrcCde)
FIN
FIN

Comment puis-je faire pour optimiser ce code ?



Cordialement !


Serviroc




Avatar
mat
serviroc wrote:
Bonjour,

J'ai pas mal de souci de lenteur sur mon système de gestion commerciale et
j'aimerais en trouver la cause.
J'ai une application en réseau WD9 avec base de données Hyperfile
Client/Server sur un Compaq Proliant ML350 avec BiProcesseur PIII 1.2Ghz et
1.2 Go De RAM.
J'ouvre un ma connexion au serveur hyperfile au démarrage de l'application !
Environ 20 personnes travaillent en simultanées.
Voici un exemple de mon code qui dure assez longtemp (une vingtaine de
secondes) :

J'accede a deux fichiers COMMANDE_CLIENT(75000 enregistrements),
ELEMENT_COMMANDE(150000 enregistrements).
Il me faut les commandes du client dont je passe le numéro en parametre ->
Num_client dans COMMANDE_CLIENT
Il me faut ensuite pour ces commandes, seulement celles ayant un element
expédiés entre les dates indiquées -> DATE_EXP dans ELEMENT_COMMANDE

reqCde = "SELECT COMMANDE_CLIENT.FACTAVOIR,COMMANDE_CLIENT.FORFAIT,
ELEMENT_COMMANDE.PXVENTE, ELEMENT_COMMANDE.DATE_EXP FROM COMMANDE_CLIENT,
ELEMENT_COMMANDE WHERE COMMANDE_CLIENT.NUM_CDE=ELEMENT_COMMANDE.NUM_CDE AND
COMMANDE_CLIENT.NUM_CLIENT='" + numéroclient + "' AND DATE_EXP BETWEEN '" +
DateDepart + "' AND '" + DateFin +"'"
Si HExécuteRequêteSQL(SrcCde,reqCde) alors
HLitPremier(SrcCde)
TANTQUE PAS Hendehors(SrcCde)

... <Suite du code>

HLitSuivant(SrcCde)
FIN
FIN

Comment puis-je faire pour optimiser ce code ?



Bonjour,

Je n'ai pas de l'expérience avec C/S HF, mais des craintes depuis
quelque temps que le moteur C/S a hérité les lenteurs des requêtes sur
HF multifichiers. Il ya un tas d'information sur ce forum (des messages
plus anciens via Google) en utilisant "lenteur" et/ou "requête" comme
mot clé. Voici quelques remarques comment j'ai réussi à accelerer les
requêtes de HF dit "classique" :

1) Éviter des liaisons WHERE en faveur de INNER JOIN ... ON ...

2) Lorsque le résultat risque d'avoir bcp de lignes, limiter la requête
à un seul fichier, dans le cas présent à ELEMENT_COMMANDE, et faire la
sélection sur le fichier lié par une sous-requête utilisant IN, en
l'occurrence le numéro client. Le WHERE ne sélectionne que le fichier
ELEMENT_COMMANDE.

3) Rechercher les valeurs de champs de fichiers liés sur le résultat de
la requête dans une boucle POUR TOUS (très rapide, que je préfère à
HLitPremier/HLitSuivant) avec HLitRecherchePremier, en évitant des
lectures multiples avec la même clé, dans le cas présent pour obtenir
les valeurs de COMMANDE_CLIENT.FACTAVOIR et COMMANDE_CLIENT.FORFAIT.

4) Éventuellement tester si >= .... AND <= .... est plus rapide que BETWEEN


Donc, j'essayerais quelque chose comme suit (j'assume que Factavoir et
Forfait sont numériques, sinon il faut mettre une chaîne vide ' '):
reqCde = "SELECT 0 AS FACTAVOIR, 0 AS FORFAIT,
ELEMENT_COMMANDE.NUM_CDE, ELEMENT_COMMANDE.PXVENTE,
ELEMENT_COMMANDE.DATE_EXP
FROM ELEMENT_COMMANDE
WHERE DATE_EXP BETWEEN '" + DateDepart + "' AND '" + DateFin +"' AND
NUM_CDE
IN (SELECT NUM_CDE FROM COMMANDE_CLIENT WHERE NUM_CLIENT='" +
numéroclient + ")
ORDER BY ELEMENT_COMMANDE.NUM_CDE "

et après exécution de la requête

vCle est entier
POUR TOUS SrcCde SUR NUM_CDE
SI vCle <> SrcCde.NUM_CDE ALORS
// numéro de commande changé
vCle = SrcCde.NUM_CDE
Si PAS HLitRecherchePremier(COMMANDE_CLIENT, NUM_CDE, vCle) ALORS
ERREUR(...) ; vCle = 0
FIN
SI vCle <> 0 ALORS
// la bonne commande a été trouvé, donc on assigne les valeurs
SrcCde.FACTAVOIR = COMMANDE_CLIENT.FACTAVOIR
SrcCde.FORFAIT = COMMANDE_CLIENT.FORFAIT
FIN
hModifie(SrcCde) // on enregistre la modif dans le résultat de la
requête, si besoin est
...
autre traitements
FIN


Ce type de code est normalement plus rapide en HF normal et j'aimerais
bien savoir si c'est la même chose avec C/S. Merci de faire un essai et
nous tenir au courant.

Salutations
Mat
Avatar
mat
...mat wrote:

Ce type de code est normalement plus rapide en HF normal et j'aimerais
bien savoir si c'est la même chose avec C/S. Merci de faire un essai et
nous tenir au courant.



J'ai oublié de dire: s'il y a beaucoup de lignes dans le résultat, les
possibilités d'optimisation sont limitées. Je suppose qu'en WD9 le
résultat de la requête réside toujours en mémoire, ce qui est un
processus relativement lent. Sous Paradox une requête donnant 100 lignes
ou 1000 lignes prend à peu près le même temps, car seulement les lignes
affichés sont lues en mémoire. Avec Windev, la 2e requête prends
beaucoup plus long pour terminer, surtout quand elle ne peut pas se
terminer en arrière plan, p.ex. à cause d'une totalisation du résultat,
d'un tri particulier ou un autre traitement voulant accéder à des
enregistrements pas encore en mémoire.
Avatar
serviroc
Bonjour

Merci beaucoup pour votre contribution, mais j'ai malheureusement un petit
problème concernant l'éxécution de la requête, elle ne retourne aucun
résultat, j'ai donc fait 2 tests, d'abord le select contenu dans la clause
IN (select num_cde from commande_client...) j'ai bien des résultats,
maintenant je remplace cette requête par les résultats précédents dans la
requête principale, ce qui me donne à peu prés ça :

reqCde = "SELECT 0 AS FACTAVOIR, 0 AS FORFAIT,
ELEMENT_COMMANDE.NUM_CDE, ELEMENT_COMMANDE.PXVENTE,
ELEMENT_COMMANDE.DATE_EXP
FROM ELEMENT_COMMANDE
WHERE DATE_EXP BETWEEN '" + DateDepart + "' AND '" + DateFin +"' AND
NUM_CDE
IN (451,542,852,420)
ORDER BY ELEMENT_COMMANDE.NUM_CDE "

et là j'ai également des résultats en retour, donc je me dis qu'il y a un
problème avec la clause IN.
Je pense avoir une idée du problème, j'ai vérifié dans l'analyse le type de
déclaration des 2 rubriques :
- COMMANDE_CLIENT.NUM_CDE : entier signé 8 octets
- ELEMENT_COMMANDE.NUM_CDE : entier signé 4 octets
Les deux sont en entier mais pas avec le meme nombre d'octet, est-ce que
cela peut être une raison ?

Cordialement

Serviroc
Avatar
mat
serviroc wrote:
Bonjour

Merci beaucoup pour votre contribution, mais j'ai malheureusement un
petit problème concernant l'éxécution de la requête, elle ne retourne
aucun résultat, j'ai donc fait 2 tests, d'abord le select contenu
dans la clause IN (select num_cde from commande_client...) j'ai bien
des résultats, maintenant je remplace cette requête par les résultats
précédents dans la requête principale, ce qui me donne à peu prés ça
:

reqCde = "SELECT 0 AS FACTAVOIR, 0 AS FORFAIT,
ELEMENT_COMMANDE.NUM_CDE, ELEMENT_COMMANDE.PXVENTE,
ELEMENT_COMMANDE.DATE_EXP FROM ELEMENT_COMMANDE WHERE DATE_EXP
BETWEEN '" + DateDepart + "' AND '" + DateFin +"' AND NUM_CDE IN
(451,542,852,420) ORDER BY ELEMENT_COMMANDE.NUM_CDE "

et là j'ai également des résultats en retour, donc je me dis qu'il y
a un problème avec la clause IN. Je pense avoir une idée du problème,
j'ai vérifié dans l'analyse le type de déclaration des 2 rubriques :
- COMMANDE_CLIENT.NUM_CDE : entier signé 8 octets -
ELEMENT_COMMANDE.NUM_CDE : entier signé 4 octets Les deux sont en
entier mais pas avec le meme nombre d'octet, est-ce que cela peut
être une raison ?



Bonjour,

Peut-être, mais je ne pense pas. Le IN ci-dessus ne marche en effet pas.
La séparation de valeurs se fait par ";" (ou TAB, je crois). Ma version
avec SELECT sur ID client devrait marcher et est probablement plus réel
pour un test. L'exemple ci-dessus sera sans doute plus rapide, mais d'où
viennent les valeurs spécifiés dan IN? Dans le code original, la
sélection des enregistrements se faisait avec un numéro client, il
faudrait maintenir cette logique pour une vrai comparaison avec le code
d'origine.

Salutations
Mat
Avatar
mat
mat wrote:
serviroc wrote:

Bonjour

Merci beaucoup pour votre contribution, mais j'ai malheureusement un
petit problème concernant l'éxécution de la requête, elle ne retourne
aucun résultat, j'ai donc fait 2 tests, d'abord le select contenu
dans la clause IN (select num_cde from commande_client...) j'ai bien
des résultats, maintenant je remplace cette requête par les résultats
précédents dans la requête principale, ce qui me donne à peu prés ça
:

reqCde = "SELECT 0 AS FACTAVOIR, 0 AS FORFAIT,
ELEMENT_COMMANDE.NUM_CDE, ELEMENT_COMMANDE.PXVENTE,
ELEMENT_COMMANDE.DATE_EXP FROM ELEMENT_COMMANDE WHERE DATE_EXP
BETWEEN '" + DateDepart + "' AND '" + DateFin +"' AND NUM_CDE IN
(451,542,852,420) ORDER BY ELEMENT_COMMANDE.NUM_CDE "

et là j'ai également des résultats en retour, donc je me dis qu'il y
a un problème avec la clause IN. Je pense avoir une idée du problème,
j'ai vérifié dans l'analyse le type de déclaration des 2 rubriques : -
COMMANDE_CLIENT.NUM_CDE : entier signé 8 octets -
ELEMENT_COMMANDE.NUM_CDE : entier signé 4 octets Les deux sont en
entier mais pas avec le meme nombre d'octet, est-ce que cela peut
être une raison ?




Bonjour,

Peut-être, mais je ne pense pas. Le IN ci-dessus ne marche en effet pas.
La séparation de valeurs se fait par ";" (ou TAB, je crois). Ma version
avec SELECT sur ID client devrait marcher et est probablement plus réel
pour un test. L'exemple ci-dessus sera sans doute plus rapide, mais d'où
viennent les valeurs spécifiés dan IN? Dans le code original, la
sélection des enregistrements se faisait avec un numéro client, il
faudrait maintenir cette logique pour une vrai comparaison avec le code
d'origine.

Salutations
Mat




En relisant le problème, je ne l'ai peut-être pas bien compris. Voici du
code à moi pour une solution similaire sur les détails d'une facture,
filtrées sur une catégorie de produits (valeur d'un champ d'une fenêtre)
à travers l'ID du produit disponible dans le détail de la facture.

"InvoiceDetail.IDProduct IN (SELECT Product.IDProduct FROM Product "+...
"WHERE Product.IDProductGroup=" +
{:cMasterWindow+".pgf.cboFltProductGroup ",indControl} + ") "

Salutations
Mat
Avatar
serviroc
La requête que j'ai decrit avec les valeurs spécifié dans le IN n'était
qu'un simple test car l'exemple de départ avec la selection sur le numéro
client ne fonctionnait pas !
Mon problème est donc que ceci ne fonctionne pas, je n'ai aucun résultat en
retour :
reqCde = "SELECT 0 AS FACTAVOIR, 0 AS FORFAIT,
ELEMENT_COMMANDE.NUM_CDE, ELEMENT_COMMANDE.PXVENTE,
ELEMENT_COMMANDE.DATE_EXP
FROM ELEMENT_COMMANDE
WHERE DATE_EXP BETWEEN '" + DateDepart + "' AND '" + DateFin +"' AND
NUM_CDE
IN (SELECT NUM_CDE FROM COMMANDE_CLIENT WHERE NUM_CLIENT='" +
numéroclient + "')
ORDER BY ELEMENT_COMMANDE.NUM_CDE "

Cordialement

Serviroc
Avatar
mat
serviroc wrote:
La requête que j'ai decrit avec les valeurs spécifié dans le IN n'était
qu'un simple test car l'exemple de départ avec la selection sur le numéro
client ne fonctionnait pas !
Mon problème est donc que ceci ne fonctionne pas, je n'ai aucun résultat en
retour :
reqCde = "SELECT 0 AS FACTAVOIR, 0 AS FORFAIT,
ELEMENT_COMMANDE.NUM_CDE, ELEMENT_COMMANDE.PXVENTE,
ELEMENT_COMMANDE.DATE_EXP
FROM ELEMENT_COMMANDE
WHERE DATE_EXP BETWEEN '" + DateDepart + "' AND '" + DateFin +"' AND
NUM_CDE
IN (SELECT NUM_CDE FROM COMMANDE_CLIENT WHERE NUM_CLIENT='" +
numéroclient + "')
ORDER BY ELEMENT_COMMANDE.NUM_CDE "



Il me semble que le NuméroClient soit définie comme valeur alpha.
Nornalement un numéro client est un numérique, non?...
Avatar
serviroc
"mat" a écrit

Il me semble que le NuméroClient soit définie comme valeur alpha.
Nornalement un numéro client est un numérique, non?...



Bonjour,

et bien non car pour mon appli les numéro de client sont sur 6 caracteres
avec les 2 premiers correspondant à leur département donc 042154 ou 094587
par exemple. Donc pour garder le zéro en première position le numéro de
client doit être en chaine.

Cordialement


Serviroc
Avatar
mat
serviroc wrote:
Bonjour,

et bien non car pour mon appli les numéro de client sont sur 6 caracteres
avec les 2 premiers correspondant à leur département donc 042154 ou 094587
par exemple. Donc pour garder le zéro en première position le numéro de
client doit être en chaine.



Bonjour,

Bon... alors il y autre chose. Le code est tellement simple, c'est
difficile de comprendre pourquoi ça ne marche pas. C'est drôle, j'ai eu
un tas de problèmes avec les requêtes HF, mais jamais avec les
sous-requêtes.

Si les 2 rubriques
- COMMANDE_CLIENT.NUM_CDE : entier signé 8 octets
- ELEMENT_COMMANDE.NUM_CDE : entier signé 4 octets
sont toujours différentes, je leur donnerais le même type pour commencer.

Salutations
Mat
1 2