Optimisation code perl CGI - Problème de performance [Perl] - Perl - Programmation
Marsh Posté le 11-06-2018 à 10:10:49
Salut,
Outre changé de langage pour un truc plus optimisé. Est-ce que tu as regardé si ta requêtes SQL était assez rapide ? (un index nécessaire ?)
Sinon, tu pourrais faire qu'une seul boucle ligne 26 qui, plutôt que tout mettre dans tabs, créerais l'HTML. Tu allongerais le temps de ta connexion à ta base, mais tu gagnerais en perf (tu enlèves un boucle ...)
Toutefois, ce prendre un timeout, c'est à dire 2min de traitement pour ca me semble assez étrange, meme pour Perl ...
Marsh Posté le 11-06-2018 à 11:27:19
Salut,
Merci pour ta réponse.
La requête en elle-même est très rapide.
Comment vois-tu la modif en ligne 26 ?
Marsh Posté le 11-06-2018 à 13:14:37
J'ai supprimé la table @tab et je travaille directement dans @row et donc dans le while de la ligne 26.
J'ai supprime le for, le résultat est le même, sur les résultats<2000 lignes ça fonctionne mais pas pour des résultats plus grands.
Marsh Posté le 11-06-2018 à 14:37:03
C'est quoi un résultat plus grand ?
On est d'accords que ton timeout est de 2min ?
Marsh Posté le 11-06-2018 à 14:55:46
Tu pourrais poster le code mis à jour?
Perso j'aurais fait:
push (@tabs,\@row)
afin d'éviter la copie de @row dans table a chaque fois et ne pas avoir une immense table @tabs
Ça plante toujours à la même ligne, si oui tu connais son numéro d'ordre? Tu as essayé avec des tables distinctes, juste pour savoir si a la base le pb n'est pas avec une ligne particulière (au delà de 2000) de la table.
A+,
Marsh Posté le 11-06-2018 à 15:17:09
Comme le résultat n'était pas plus satisfaisant j'ai supprimé le code mis à jour, je vais le recréer.
Merci pour le push (@tabs,\@row).
Oui ça plante toujours à la même ligne, qu'entends-tu par tester avec des tables distinctes ?
@dedes_sav, le timeout est bien de 2 minutes et résultat plus grand c'est à dire >2000 lignes.
Marsh Posté le 11-06-2018 à 15:40:54
Re,
Voici mon code mis a jour:
Code :
|
Marsh Posté le 11-06-2018 à 18:19:09
> Oui ça plante toujours à la même ligne, qu'entends-tu par tester avec des tables distinctes ?
Je ne parlais pas de la ligne de code perl, mais de la ligne de la BDD, au cas ou ce soit les données de la BDD qui fassent échouer la requête.
Tu peux pas mettre un compteur pour voir si c'est la même ligne requêtée de la BDD qui échoue toujours ?
my $cpt = 0;
while (my @row = $sth->fetchrow_array())
{
print ++$cpt; # ou print dans un log au vu de ce que fait print dans ton code
Si le plantage est systématiquement a la même position, soit une donnée de la BDD fait échouer la requête, soit le nb de requêtes a atteint une limite à modifier. Sinon, ça a plus de chances d'être un vrai pb de timeout réseau
A+,
Marsh Posté le 12-06-2018 à 09:40:47
Merci Gilou,
Voici ce que j'ai fait :
Code :
|
J'écris ma page dans un fichier (dans /result/$param.html) ensuite j'affiche une page qui propose un liens vers le fichier généré pour le télécharger.
Résultat, si je génère mon fichier sur une petite log, pas de problème, le fichier est généré et le lien de téléchargement fonctionne très bien.
Si je génère mon fichier sur une grosse log, alors le fichier est bien généré dans /result/$param.html, il est complet, mais ma page avec le lien de téléchargement ne s'affiche jamais et je termine de nouveau en timeout
Le problème est donc ailleurs ? une idée à la vu du code ?
Marsh Posté le 12-06-2018 à 13:41:03
Euh, et si tu testes avec une boucle a vide, et aucun autre code parasite, ça plante aussi?
while (my @row = $sth->fetchrow_array()) {}
> Si je génère mon fichier sur une grosse log, alors le fichier est bien généré dans /result/$param.html, il est complet, mais ma page avec le lien de téléchargement ne s'affiche jamais et je termine de nouveau en timeout
Donc en fait le pb n'a rien a voir avec la BDD, c'est ton chargement de la page html générée qui échoue, c'est bien ça?
A+,
Marsh Posté le 12-06-2018 à 13:51:37
Merci Gilou, oui c'est bien ça
Pourtant j'ai d'autre pages sur le même model qui fonctionnent parfaitement, et cette même page fonctionne si le résultat de la requête SQL, donc le fichier généré, n'est pas trop grand !
je vais tester le while à vide.
Marsh Posté le 12-06-2018 à 13:54:35
Je viens de tester avec la boucle à vide et ça fonctionne dans tous les cas
Marsh Posté le 13-06-2018 à 16:12:28
Le problème est donc dans cette partie, et tout à fait en dehors du code DBI :
Code :
|
Tu as essayé en augmentant le timeout?
A+,
Marsh Posté le 14-06-2018 à 16:21:57
Oui j'ai augmenté le timeout sans plus de succès.
Je ne pense pas que le problème vienne de la partie que tu cite car elle fonctionne parfaitement quand le résultat de la requête est petit.
J'ai encore modifié le code pour limiter les IO, je mets tout dans une variable et j'écris le fichier d'un coup.
Code :
|
Je suis allé plus loin dans mes tests, si je mets en commentaire le else dans le if du while alors ça fonctionne :
Code :
|
C'est donc la ligne
Code :
|
qui pose problème.
Dans les logs de mon serveur Web je vois pourtant que la page renvoie un code 200 même quand je tombe en timeout
Marsh Posté le 14-06-2018 à 17:10:00
J'ai trouver la solution
C'est la variable $res qui posait problème quand elle est vide.
J'ai donc ajouté ce contrôle dans le else:
Code :
|
On peut peut-être faire plus propre ?
Marsh Posté le 08-06-2018 à 10:39:08
Bonjour,
Je vous explique le context.
Je dois requêter une base de données (SQL Server) pour générer un tableau de log.
Lorsque le tableau est "petit", c'est à dire<2000 lignes, mon code fonctionne parfaitement et la page s'affiche rapidement.
Par contre quand le nombre de lignes de ma requête SQL est plus important et bien je tombe en time out et ça ne fonctionne plus.
Voici mon code :
Avez vous des pistes pour optimiser ce code ?
J'essaie de réduire le nombre d’itérations de ma boucle for mais sans succès
Merci pour votre aide.