Bonjour,
Petite question avec cette méthode
Comment savoir que le remplissage est terminée ? Car si on fait un un HLibereRequete trop tot, le remplissage est incomplet.
Merci
Bonjour,
Petite question avec cette méthode
Comment savoir que le remplissage est terminée ? Car si on fait un un HLibereRequete trop tot, le remplissage est incomplet.
Merci
Bonjour,
Je crois que vous partez dans tous les sens et que vous devriez procéder plus systématiquement, si vous voulez faire des tests.
Si vous comparez d'emblée un remplissage A avec un affichage B à un remplissage C avec un affichage A, vous ne vous en sortirez jamais.
Ce n'est qu'une fois vos tests de remplissage et d'affichage bien systématisés que vous pourrez commencer à tester des mix, sans vous prendre les pinceaux.
Choisir un ou deux fichiers, pourquoi pas le vôtre et celui des codes postaux que vous avez déjà utilisés. Si vos tests varient dans le même sens sur deux fichiers, votre méthode a plus de chance d'être satisfaisante sur un troisième etc.
Ensuite, tester vos remplissages dans les 2, voire 3 cas de figure, càd table mémoire, table fichier (fichier ou requête) et table fichier chargée en mémoire.
Il n'y a pas d'autres types de table à considérer ici.
Il faut retenir qu'il y a des différences de comportement ou de fonctions disponibles suivant le type de table. par exemple SQLTable n'est utilisable que sur une table mémoire alors que ConstruitTableFichier est utilisable sur les deux types de tables.
Là, vous testez vos méthodes de remplissage : TableAjouteLigne, SQLTable, ConstruitTableFichier., sans vous préoccuper du reste.
Après cela, vous pourrez tenter d'optimiser vos requêtes et vos boucles de parcours H.
Ensuite, il faudra décider si vous voulez afficher vos données dès que possible (en bref, il faut rapidement donner quelque chose à l'utilisateur) ou si vous voulez n'afficher vos données qu'une fois l'intégralité disponible parce qu'autrement l'utilisateur ne pourrait pas travailler (par ex, il va systématiquement trier selon l'une ou l'autre colonne, ce qui implique que la table soit remplie)
Là, vous déciderez de toutes les tactiques qui accélèrent le remplissage complet / la mise à disposition partielle mais rapide (avec des à côté qui dépendent des traitements de la table : effet de clignotement etc. voir les nombreux sujets qui en traitent).
Et le choix final pourrait se porter vers une table qui est plus vite affichée mais moins rapidement remplie si vous voulez que votre utilisateur puisse rapidement commencer à lire.
Càd que ce sera toujours un compromis !
-----
Vous devez aussi réfléchir aux données que vous voulez afficher en première intention. Je suppose que vous n'affichez pas d'emblée les 10.000 fiches avec leur +/- 400 car. et le commentaire de 65.500 car.
Donc vous rapatriez les 4 - 5 colonnes de base (nom, prénom, sexe, date de naissance, liste noire par exemple) et quand l'utilisateur veut en savoir plus, vous allez lire le reste de la fiche.
Auditeur.Commentaires pourrait d'ailleurs être un mémo.
Le recours au fichier référence Codes postaux que je vous proposais serait lu à ce moment et ne pénaliserait donc pas votre requête.
Pour ce qui est des techniques d'optimisation de vos requêtes, vous pouvez aussi consulter Optimisez votre SGBDR et vos requêtes SQL dans les Tutoriels SQL.
Désolé, je n'ai pas été très clair
En fait, le remplissage ne se passe dans un thread secondaire
Par contre la table est remplie par bloc de X lignes
On fait une boucle du type :Je fais un multitâche(-1) pour avoir la main à chaque bloc, ici toutes les 1000 lignes
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 TANTQUE SQLTable(1000, "Req1", Table_Result_Data..Nom) // Ici on peut par exemple tester une variable pour arrêter le remplissage Multitache(-1) FIN SQLFerme("Req1")
Bien sur, si la valeur du bloc est trop importante, on aura difficilement la main
Quand on arrive au SQLFerme le remplissage est terminé
On n'est pas du tout dans le cas d'un remplissage dans un thread secondaire, mais ça permet quand même d'intervenir pendant le remplissage (avec des contrôles sur ce qu'on autorise à faire bien sur)
Pascal H.
phapps.e-monsite.com
Je viens de faire un test de performance de différentes méthodes pour remplir une table.
A partir d'un requête qui retourne 30000 enregistrement
Le chrono débute après l'exécution de la requête juste avant de remplir la table.
Il est arrêté à la fin du remplissage.
L'intérêt des temps relevés et de les comparer entre les différente méthodes
1 - TableAffiche() : 7,7 sec
2 - ..FichierParcouru : 7,7 sec
3 - HLitPremier() + TANTQUE HTrouve() + TableAjouteLigne(): 4,6 sec
4 - POUR TOUT + TableAjouteLigne(): 4,2 sec
5 - ConstruitTableFichier() : 4,0 sec
6 - La méthode préconisée par hpascal
Premier lot de ligne affiché : 0,2 sec
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 TANTQUE SQLTable(1000, "Req1", Table_Result_Data..Nom) // Ici on peut par exemple tester une variable pour arrêter le remplissage Multitache(-1) FIN SQLFerme("Req1")
Remplissage complet : 5,8
Par cette méthode le remplissage complet n'est pas le plus performant.
Mais ce qui est très intéressant c'est la perception par l'utilisateur d'un affichage quasi immédiat... quelque soit le nombre de ligne retourné par la requête... vraiment très intéressant...
Les remarques de Hemgé sont très pertinentes, notamment de réfléchir s'il faut vraiment que toute les données soient dans la table ou si certaines rubriques peuvent être affichées dans une fiche rempli lors de la sélection d'une ligne.
La jointure que tu peux éviter
L'éditeur de requête a généré la jointure entre les 3 fichiers parce que tu sélectionnes des rubrique du fichier Auditeur et tu fais une condition sur une rubrique du fichier Radio (Radio.IDRadio). Pour pouvoir relier les 2 fichiers il est obligé de passer par le fichier Radio_Auditeur.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 +------------+ +------------------+ +---------+ | Auditeur | | Radio_Auditeur | | Radio | +------------+ +------------------+ +---------+ | IDAuditeur |--->| IDRadio_Auditeur |<---| IDRadio | | ... | | IDAuditeur | | ... | +------------+ | IDRadio | +---------+ +------------------+
La rubrique IDRadio est aussi dans le fichier Radio_Auditeur. Si tu fais ta condition sur cette rubrique, tu verras que l'éditeur de requête n'aura pas à faire de jointure avec le fichier Radio.
Le IN en SQL correspond à la condition "est dans la liste" de l'éditeur de requête. Mais comme je t'ai dis je ne suis pas sur que ça fasse gagner en performance.
Bon dev
Laurent
- C’est génial.
- Non c’est bizarre.
- Justement quand c’est simple y’a des milliers de réponses et quand c’est bizarre y’en a aucune.
Bonjour,
Tu as fais les tests sur un fichier et une requête similaire à la mienne ?
J'ai ces temps de traitement pour seulement 8000 à 10 000 enregistrements, j'ose pas imaginer pour 30 000
Je pense rester sur POUR TOUT + TableAjouteLigne. ConstruitTableFichier ne me conviens pas, il gère seul les colonnes et ça ne me conviens pas vraiment.
J'ai ajouté une jauge dans ma fenêtre pour faire patienter l'utilisateur, il vois au moins qu'il se passe quelque-chose.
SQLTable c'est pas mal mais ça met plus de temps au final et je doit passer par SQLConnect etc... et je n'ai plus de correction de la requête contre les l'injections ?
Et même, si on rend la main à l'utilisateur de temps en temps, ça ne reste pas assez fluide pour faire d'autres actions Ou alors mon PC rame...
Pour ce qui est de l'optimisation de la requête, je ne récupère vraiment que ce dont j'ai besoin, j'ai viré commentaires, adresse etc...
Le reste est chargé au cas par cas dans une fiche.
Du coté de la jointure, je regarderais en virant la jointure sur Radio ce que ça donne
Je viens de faire un test basique : Créer une nouvelle fenêtre vierge et une nouvelle table fichier en mémoire lié à une requête qui liste toutes les données que j'ai besoin et bien l'affichage est immédiat !
Donc je dois avoir un soucis avec ma table de départ...
EDIT : Je viens de faire une découverte intéressante... C'est la rubrique de parcours qui fait que le chargement est long ou pas !
Si je spécifie en rubrique de parcours l'IDAuditeur, ça va ramer et m'afficher d'un coup la table une fois complètement chargée mais si je sélectionne "Automatique", la table va s'afficher tout de suite et ensuite le chargement se fait selon les besoins.
Donc c'est cool on avance par contre, j'ai besoin d'utiliser une requête SQL créée de mes mains et non par l'éditeur de requête et je ne vois pas comment lui dire "Automatique" par programmation
Une idée ?
Merci.
Bon après plusieurs tests divers, c'est la requête qui est pourri et windev ne l'aime pas...
Une requête simple sans liaisons avec d'autres fichiers, fonctionne impec ! L'affichage se fait au fur et à mesure si besoin.
Mais dès que je souhaite avoir les auditeurs liés à tel radio, c'est la cata ! Pas d'affichage de la fenêtre et après quelques secondes la table totalement remplie
Je désespère, je ne sais plus quoi faire
EDIT :
Après moulte bidouilles en SQL, je m'en rend compte que c'est mon ORDER BY Nom ASC qui fout la merde et qui ralenti tout ... Sans order by, l'affichage est immédiat dans la table.
Je souhaite afficher les auditeurs dans l'ordre des noms mais si je fais un tabletrie ensuite, cela rame de nouveau :s
Une idée svp ?
Merci à tous !
EDIT 2 :
Je viens de me rendre compte que je bossait en local et quand je suis repassé en C/S, les temps étaient de nouveaux mauvais pffff
J'ai tenté de surnommer les fichiers mais rien de meilleur coté temps de traitement après "ne pas préfixer vos noms de colonne", qu'entendez-vous par là ?
Je voudrais bien savoir pourquoi une requête simple avec un SELECT fonctionne, la table est affichée immédiatement et ça se rempli au fur et à mesure alors que dès que j'utilise un SELECT DISTINCT et un ORDER BY la table attends son chargement complet pour s'afficher
On m'as proposé de changer de SGDB mais est-ce vraiment là le soucis ?
Merci.
Vous avez un certain nombre de réponses au bout du lien que je vous ai proposé. Inutile de les répéter ici.
DISTINCT et ORDER BY : si vous réfléchissez à leur action, cela ne devrait pas vous étonner qu'ils aient besoin de charger toute la requête avant de pouvoir exercer leurs fonctions spécifiques.
Si tu veux faire un order by par nom d'auditeur, il faut que cette colonne soit indexée, sinon, le HFSQL va d'abord charger tout le fichier puis le trier.
Pour rappel l'indexation sert à ordonner une colonne...
Voilà l'aide de WinDev pour les index avec HFSQL : http://doc.pcsoft.fr/fr-FR/?3044133
Par contre, je ne connais pas du tout l'indexation sur HFSQL, si c'est performant ou pas, si on peut avoir plusieurs indexes, ...
C'est là l'avantage d'un "vrai" SGBD où la fiabilité et la performance n'est plus à prouver.
Bonsoir,
Nom est bien indexée non ? J'ai mis la rubrique en clé.
Je suis de plus en plus tenté par un "vrai" SGBD comme sql server express par exemple mais compliqué à mettre en place ?
Merci.
Bonsoir,
"Vrai" SGBD ou pas, commencez par simplifier le problème en réfléchissant à des contraintes réalistes.
De la même manière que vous n'avez pas à rapatrier l'intégralité de chaque fiche (et vous avez simplifié depuis lors), vous n'avez pas à rapatrier 10.000 références.
Personne ne va raisonnablement prétendre examiner cette masse d'informations.
Donc, quel(s) critère(s) de sélection pouvez-vous adopter pour revenir à un objectif raisonnable ?
Quelle que soit la performance de votre application, rapatrier 10.000 références sera toujours notablement plus long qu'en rapatrier 200, 500 ou même 1000.
Idem pour l'alimentation de la table.
Et ce, en pure perte puisque personne n'exploitera l'intégralité. C'est une simple question de bon sens.
Quitte à ce que l'utilisateur fixe au cas par cas les critères à exploiter et/ou les valeurs de ces critères.
Franchement SQL Server Express n'est vraiment pas sorcier à installer. Bien regarder les pré-requis avant, ouvrir les ports qui vont bien sur le réseau et lors de l'installation, tout se déroule tranquillement.
MySQL peut aussi faire l'affaire si tu veux un OS linux qui ne coûte rien (CentOS par exemple).
La tendance du moment est aussi à postgreSQL mais je ne connais pas du tout et il me semble qu'on n'est pas tout à fait sur du SQL. La communauté commence à s'étoffer et c'est moins risqué de s'y lancer.
On sort un peu du post pour un débat SGBD, mais tant qu'à changer SGBD, vaut mieux SQLServer express qu'un MySQL ou PostgrSQL qui sont loin d'être aussi performant.
Pour revenir au post,Avoir une clé n'est pas forcément synonyme d'indexation, donc c'est loin d'être sûr que cette colonne est indexée.Envoyé par WDKyle
Bonjour,
Je conçois que récupérer 10 000 enregistrements c'est beaucoup mais j'ai besoin que l'utilisateur fasse des recherches, filtres sur les auditeurs et donc il à besoin de tout le contenu dans la table ...? Ma fenêtre de base est assez grande avec des ancrages, la table prend la plus grande partie de la fenêtre si je ne met rien dans cette table cela ne sera pas très esthétique...
Ce n'est pas l'installation le soucis, mais l'exploitation avec Windev en OLE DB car je n'y connais rien... Je vais perdre la facilité que j'ai avec HFSQL.
Ah... C'est bon à savoir ! Car dans l'aide en ligne pour eux une clé c'est un index... Comment faire alors ?
Merci !
Pour HFSQL, je ne sais pas du tout comment il gère les index donc je me prononce pas...
Je ne fais que du SQLServer en ODBC et je t'affirme qu'une clé n'est pas forcément indexée.
Faire du WinDev en utilsant pas HFSQL a comme tu dis des inconvénients, mais personnellement, les ordres H*, fichierversecran, ... sont vraiment... déroutant je dirais.
C'est simplissime à utiliser jusqu'à ce que tu veux faire un truc qui sort en dehors des clous de WinDev, et là tu galères.
Moi j'ai choisi de ne passer que par des ordres SQL* et de faire de l'accès aux données manuelles. (pas d'accès natif non plus)
Je fais ma requête comme je veux pour obtenir exactement ce que je veux (=> Comme ça tu peux voir la performance de la requête simplement)
Je remplis manuellement mes tables, champs, ...
Ca demande peut être un peu plus de boulot au départ (mais vraiment pas beaucoup) et après t'as aussi un code super lisible et tu maitrises à 100% ce que tu fais.
Bref, tout ça pour dire que si on utilise les méthodes données par WinDev (pour soit disant simplifier l'écritures du code et pouvoir changer de base de données sans changer le code et autre truc inutile), il vaut mieux savoir ce qu'on fait, parce que quand ça déconne, va comprendre le mécanisme interne des fonctions avancées que t'as utilisé (comme ce problème de lenteur ! 3 pages de threads et on commence seulement à comprendre)
D'accord, mais avec des ordres SQL* cela gère l'intégrité de la base ? Les jointures, etc... ?
C'est compliqué à mettre en place une connexion ODBC vers SQLServer ? Ou OLEDB (dépassé ?) ?
Merci.
Une connexion ODBC est tout ce qu'il y a de plus simple :
Installation du client SQL correspondant à la version de ta partie serveur
Paramétrage à faire comme n'importe quel ODBC (serveur, user/password ou utilisateur windows, base, ...)
Tu peux définir la connexion dans la liste des connexions de l'analyse pour mapper les tables (existantes) et faire la connexion dans le code pour le programme.
Ok, et bien je vais faire des tests
Par contre, HCréationSiInexistant ne fonctionnera plus ? Il faut que je crée mes tables SQL avec les fonctions SQL* ?
Merci.
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager