IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

Problème de performance (très lent)


Sujet :

Langage PHP

  1. #1
    Membre confirmé
    Inscrit en
    Avril 2004
    Messages
    102
    Détails du profil
    Informations personnelles :
    Âge : 47

    Informations forums :
    Inscription : Avril 2004
    Messages : 102
    Par défaut Problème de performance (très lent)
    Tout d'abord, je dois vous prévenir que je suis encore assez novice dans la programmation en php

    Voici mon problème.
    J'ai développé une application qui permet de gérer les chargements des camions dans mon entreprise.
    Les ventes encodent les commandes 1 par 1 et le magasin complète le tout au fur et à mesure de l'avancement du travail. La vue au niveau magasin est sous la forme d'un formulaire par livraison, ce qui peut représenter plus de 200 formulaires affichés les uns en dessous des autres (il n'y a que les livraisons de la semaine qui apparaissent).

    Je ne connais absolument pas les besoins en ressource d'un serveur PHP, ni d'une station "cliente", toujours est-il que lorsqu'on affiche la page contenant tous ces formulaires, il faut facilement 2-3 minutes avant que tout ne soit charger et pendant ce temps, le PC est à 100% d'utilisation du CPU. Si on valide des formulaires, ça peut prendre plus de 5 minutes avant qu'elle ne soit accessible à nouveau.

    Est-ce que quelqu'un peut m'aider, car ça devient très problématique ?

    Merci d'avance.

  2. #2
    Expert confirmé Avatar de Mr N.
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    5 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 5 418
    Par défaut
    Ah les perfs....
    Il faut tout d'abord que tu détermine le bottleneck :
    - est-ce les requêtes à la db qui prenent du temps ?
    - est-ce le traitement php ?

    Pour ça je te suggère d'utiliser l'exemple 568 pour détecter la portion de code qui prend du temps

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    <?php
    $time_start = microtime_float();
     
    $res = mysql_query('SELECT * FROM formulaires WHERE ....');
     
    $time_end = microtime_float();
    echo '<b>La requête a pris '. $time_end - $time_start .' secondes</b>';
    ?>

  3. #3
    Membre confirmé
    Inscrit en
    Avril 2004
    Messages
    102
    Détails du profil
    Informations personnelles :
    Âge : 47

    Informations forums :
    Inscription : Avril 2004
    Messages : 102
    Par défaut
    Merci beaucoup.

    Lorsque j'affiche le temps d'exécution de ma requete qui va chercher les données dans la table, ça me donne : -1175087155.61 secondes.

    Une valeur négative ???

  4. #4
    Expert confirmé Avatar de Mr N.
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    5 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 5 418
    Par défaut
    Fais voir le bout de code en question ?

  5. #5
    Membre confirmé
    Inscrit en
    Avril 2004
    Messages
    102
    Détails du profil
    Informations personnelles :
    Âge : 47

    Informations forums :
    Inscription : Avril 2004
    Messages : 102
    Par défaut
    Voici une partie du code, parce que le reste (càd la création des formulaires) est très très long.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function encodageWh()
    {
      require_once('././Modeles/delivery.class.php'); //Appel de la fonction qui ramène les données du la db
     
      $time_start = microtime_float();
      $myDelivery=new Delivery();
      $tableau=$myDelivery->getDeliveries();
      $time_end = microtime_float();
      echo '<b>La requête a pris '. $time_end - $time_start .' secondes</b>';
    ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    <?php
    //Sélection des données de la db
    require_once('connexion.class.php');
     
    class Delivery
    {
     
      var $connexion;
      var $week;
      var $customer;
      function Delivery()
      {
        $this->connexion = new Connexion();
        $this->week = date("W");
      }
     
      function getDeliveries()
      {
        $requete=mysql_query("SELECT * FROM delivery INNER JOIN customers ON delivery.customer_id = customers.id INNER JOIN users ON delivery.user_id = users.id where week >= '.$this->week.' order by prepa_date, load_date, load_time, name, od;");
        $total=array();   
        while ($resultat=mysql_fetch_object($requete))
        {
          array_push($total,$resultat); 
        }
        return($total);
      }

  6. #6
    Expert confirmé Avatar de Mr N.
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    5 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 5 418
    Par défaut
    Elle est définie où la fonction microtime_float() ?

  7. #7
    Membre confirmé
    Inscrit en
    Avril 2004
    Messages
    102
    Détails du profil
    Informations personnelles :
    Âge : 47

    Informations forums :
    Inscription : Avril 2004
    Messages : 102
    Par défaut
    Juste avant la fonction encodageWh()

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    <?php
     
    function microtime_float()
      {
        list($usec, $sec) = explode(" ", microtime());
        return ((float)$usec + (float)$sec);
      }
     
    //Fonction qui crée le tableau du planning chargement
    function encodageWh()
    {
      require_once('././Modeles/delivery.class.php'); //Appel de la fonction qui ramène les données du la db
     
      $time_start = microtime_float();
      $myDelivery=new Delivery();
      $tableau=$myDelivery->getDeliveries();
      $time_end = microtime_float();
      echo '<b>La requête a pris '. $time_end - $time_start .' secondes</b>';
    ...

  8. #8
    Expert confirmé Avatar de Mr N.
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    5 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 5 418
    Par défaut
    Ok. peux tu remplacer ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function encodageWh()
    {
      require_once('././Modeles/delivery.class.php'); //Appel de la fonction qui ramène les données du la db
     
      $time_start = microtime_float();
      $myDelivery=new Delivery();
      $tableau=$myDelivery->getDeliveries();
      $time_end = microtime_float();
      echo '<b>La requête a pris '. $time_end - $time_start .' secondes</b>';
    ...
    Par ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    function encodageWh()
    {
      require_once('././Modeles/delivery.class.php'); //Appel de la fonction qui ramène les données du la db
     
      $time_start = microtime_float();
    var_dump($time_start);
      $myDelivery=new Delivery();
      $tableau=$myDelivery->getDeliveries();
      $time_end = microtime_float();
    var_dump($time_end);
      echo '<b>La requête a pris '. $time_end - $time_start .' secondes</b>';
    ...
    Quel est le résultat des deux var_dump ?

  9. #9
    Membre confirmé
    Inscrit en
    Avril 2004
    Messages
    102
    Détails du profil
    Informations personnelles :
    Âge : 47

    Informations forums :
    Inscription : Avril 2004
    Messages : 102
    Par défaut
    Voici les résultats que j'ai :
    float(1175090303.98) float(1175090304.29) -1175090303.98 secondes

  10. #10
    Expert confirmé Avatar de Mr N.
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    5 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 5 418
    Par défaut
    essaie de mettre des parentheses :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    echo '<b>La requête a pris '. ($time_end - $time_start) .' secondes</b>';
    Désolé pour la perte de temps que je t'ai causé

  11. #11
    Membre confirmé
    Inscrit en
    Avril 2004
    Messages
    102
    Détails du profil
    Informations personnelles :
    Âge : 47

    Informations forums :
    Inscription : Avril 2004
    Messages : 102
    Par défaut

  12. #12
    Expert confirmé Avatar de Mr N.
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    5 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 5 418
    Par défaut
    Je pense que ça vaut le coup de continuer dans tes investigation. Est-ce que c'est le for ? le while ? le deuxième while ? le troisième qui prend du temps ?

    Sinon essaie de faire un echo de tes données de temps en temps au lieu de faire une énorme concaténation. Ca ne va pas résoudre le problème de lenteur, mais ça permettras d'afficher des données à l'utilisateur

  13. #13
    Membre confirmé
    Inscrit en
    Avril 2004
    Messages
    102
    Détails du profil
    Informations personnelles :
    Âge : 47

    Informations forums :
    Inscription : Avril 2004
    Messages : 102
    Par défaut
    Lorsque je calcule le temps d'exécution de toutes la création du formulaire (je démarre le compteur juste avant le "FOR"), j'ai le résultat suivant : La requête a pris 0.490092992783 secondes

    J'en déduit donc que ce n'est pas là que ce trouve le problème.

    Est-ce que ça pourrait provenir de ma page d'origine, qui appelle la fonction de création des formulaires et qui les affiche ???

    Pour en être certain, je poste ci-dessous le code de cette page.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    <?php 
     
    require_once('Traitements/traitementTable.php');
    switch ($_SESSION['group']) // Contrôle le groupe d'autorisation
    {
      case 'customer':
        if (isset($_POST['add']))
        {
          $addDelivery = addDelivery();
        }
        if (isset($_GET['control']))
        {
          $view=customerAct($_GET['control'], $_GET['id'], $_GET['od']);
        }
        else
        {
          $view=controler();
        }
        if (isset($_POST['modif']))
        {
          $modifDelivery = modifDelivery();
        }
      break;
     
      case 'wh' :
        if (isset($_POST['submit']))
          {
            list($indice, $value) = each($_POST['submit']);
            foreach ($_POST['id'][$indice] AS $k => $v)
            {
              $modifWh = modifWh($_POST['id'][$indice][$k], $_POST['prepaDate'][$indice][$k], $_POST['od'][$indice][$k], $_POST['wave'][$indice][$k], $_POST['ot1Nb'][$indice][$k], $_POST['ot1Area'][$indice][$k], $_POST['ot1Qty'][$indice][$k], $_POST['ot1Status'][$indice][$k],
                                              $_POST['ot2Nb'][$indice][$k], $_POST['ot2Area'][$indice][$k], $_POST['ot2Qty'][$indice][$k], $_POST['ot2Status'][$indice][$k], $_POST['ot3Nb'][$indice][$k], $_POST['ot3Area'][$indice][$k], $_POST['ot3Qty'][$indice][$k], $_POST['ot3Status'][$indice][$k],
                                              $_POST['ot4Nb'][$indice][$k], $_POST['ot4Area'][$indice][$k], $_POST['ot4Qty'][$indice][$k], $_POST['ot4Status'][$indice][$k], $_POST['ot5Nb'][$indice][$k], $_POST['ot5Area'][$indice][$k], $_POST['ot5Qty'][$indice][$k], $_POST['ot5Status'][$indice][$k],
                                              $_POST['ot6Nb'][$indice][$k], $_POST['ot6Area'][$indice][$k], $_POST['ot6Qty'][$indice][$k], $_POST['ot6Status'][$indice][$k], $_POST['ot7Nb'][$indice][$k], $_POST['ot7Area'][$indice][$k], $_POST['ot7Qty'][$indice][$k], $_POST['ot7Status'][$indice][$k],
                                              $_POST['ot8Nb'][$indice][$k], $_POST['ot8Area'][$indice][$k], $_POST['ot8Qty'][$indice][$k], $_POST['ot8Status'][$indice][$k], $_POST['ot9Nb'][$indice][$k], $_POST['ot9Area'][$indice][$k], $_POST['ot9Qty'][$indice][$k], $_POST['ot9Status'][$indice][$k],
                                              $_POST['ot10Nb'][$indice][$k], $_POST['ot10Area'][$indice][$k], $_POST['ot10Qty'][$indice][$k], $_POST['ot10Status'][$indice][$k], $_POST['crates'][$indice][$k], $_POST['note'][$indice][$k]);
            }
          } 
      break; 
     
      case 'traffic' :
        if (isset($_POST['submit']))
          {
            list($indice, $value) = each($_POST['submit']);
     
            $l = "";
            foreach ($_POST['id'][$indice] AS $k => $v)
            {
              if ($_POST['customer'][$indice][$k] == $_POST['customer'][$indice][$l] && $_POST['loadDate'][$indice][$k] == $_POST['loadDate'][$indice][$l] && $_POST['loadTime'][$indice][$k] == $_POST['loadTime'][$indice][$l])
              {}
              else 
              {
                $export = exportation($_POST['id'][$indice][$k], $_POST['customerId'][$indice][$k], $_POST['loadDate'][$indice][$k], $_POST['loadTime'][$indice][$k], $_POST['truck'][$indice][$k]);
                $l = $k;
              }
              $modifTraffic = modifTraffic($_POST['id'][$indice][$k], $_POST['loadDate'][$indice][$k], $_POST['loadTime'][$indice][$k], $_POST['truck'][$indice][$k]);           
            }
          }
      break; 
    }
    ?>
     
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" >
     
    <head>
      <title>Planning Chargement</title>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
      <link rel="stylesheet" media="screen" type="text/css" title="Design" href="Styles/planning.css" />
    </head>
     
    <body>
      <!--Va chercher ce qu'il doit afficher en en-tête-->
      <?php
      include('includes/header02.html');
     
      switch ($_SESSION['group']) // Contrôle le groupe d'autorisation
      {
        case 'customer':
     
          //Formulaire d'encodage du planning
          echo $view['form'];
     
          //Table complète
          echo $view['table'];
        break;
     
        case 'wh' :
          //Formulaire pour le WH
          $view=controler();
          echo $view;
        break;
     
        case 'traffic' :
          //Formulaire pour le traffic
          $view=controler();
          echo $view;
      }
      ?>
     
    </body>
     
    </html>

  14. #14
    Membre expérimenté Avatar de daniel61
    Inscrit en
    Décembre 2006
    Messages
    139
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 139
    Par défaut
    juste pour être certain à mon tour, est-ce qu'il y a réellement affichage de 9000 input/select coté client ?

  15. #15
    Membre confirmé
    Inscrit en
    Avril 2004
    Messages
    102
    Détails du profil
    Informations personnelles :
    Âge : 47

    Informations forums :
    Inscription : Avril 2004
    Messages : 102
    Par défaut
    Il y a 51 champs par livraison à afficher dans le formulaire.
    A raison de 200 - 250 livraisons au maximum par semaine, fais le calcul il y a entre 10.200 et 12.750 input/select à l'écran.

    Je suis novice en la matière, donc je ne sais réellement pas si ça a une influence sur les performances de l'application.
    Si c'est le cas, existe-t-il une solution ?

  16. #16
    Expert confirmé Avatar de Mr N.
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    5 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 5 418
    Par défaut
    Essaie de générer une page normale (sans tes benchmarks)
    tu l'enregistre en page html a l'aide du browser
    tu stockes cette page sur ton serveur
    tu appelles cette page, et regarde combien de temps il met pour s'afficher (tu peux utiliser javascript en stockant l'heure dans les headers et arretant le timer lors du body.onload)

  17. #17
    Membre éprouvé
    Avatar de Rakken
    Homme Profil pro
    Inscrit en
    Août 2006
    Messages
    1 257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 257
    Par défaut
    1 for et 3 while, ca fait quatre boucle imbriquée, c'est beaucoup.
    Fait un tests simple, tu initialises 4 compteurs a zero avant ton for, et tu en place un a chaque niveau de boucle (genre juste en dessous du for/while).
    Et juste apres ton for, tu affiche le contenu de tes compteur. Comme ca tu verras si c'est lent parce que tu as un nombre très grand de boucle (ce que je pense être le cas) ou si c'est parce que un des traitements dans une boucle est long.

    Dans un cas comme ca, avec plusieurs boucles imbriquée, il faut essayer de réduire au max le nombre d'iteration de chaque boucle. En addmetant que tu n'ai que 10 cas a tester a chaque boucle, tu as 10 (for) * 10 (while1) * 10 (while2) *10 (while3) = 1000 itérations.
    Si une des boucles a 100 tests a faire, tu passe directement a 10 000 iterations, et ca monte très vite.

    Donc les solutions envisageable : Est-il possible, en trouvant un autre algo de supprimer un ou deux boucles ?
    Si ce n'est pas le cas, est ce qu'il est possible de sortir des boucles avant d'avoir tout testé ? (tests redondant).
    J'ai déjà eu a optimiser des boucles imbriqué comme ca, je suis passé de 1 000 000 d'itérations (la page mettait de 30sec a 5mn pour s'afficher, suivant la quantité de donnée a traiter) à a peine 100 000 (affichage descendu en dessous de 5 secondes).
    C'est un travail de longue haleine, mais avec le code que tu as eu pour voir le temps que prend chaque portion de code et un peu de courage, ca se fait ;-))

  18. #18
    Membre confirmé
    Inscrit en
    Avril 2004
    Messages
    102
    Détails du profil
    Informations personnelles :
    Âge : 47

    Informations forums :
    Inscription : Avril 2004
    Messages : 102
    Par défaut
    Pour Mr N.

    Je viens d'effectuer ce test et il met approximativement le même temps pour afficher la page.

    Vaut-il mieux que j'essaie de réduire au maximum le nombre d'input/select ?

    Pour Rakken
    J'ai déjà effectuer les tests sur toutes mes boucles et je ne dépasse que très rarement la second pour une boucle complète, donc je pense que le problème vient plutôt de l'affichage simple.
    Le test précedent confirme mes craintes.

  19. #19
    Expert confirmé Avatar de Mr N.
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    5 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 5 418
    Par défaut
    est-ce que le temps est identique en local ? (en appelant directement la page sauvegardée localement)

  20. #20
    Membre confirmé
    Inscrit en
    Avril 2004
    Messages
    102
    Détails du profil
    Informations personnelles :
    Âge : 47

    Informations forums :
    Inscription : Avril 2004
    Messages : 102
    Par défaut
    Non, j'ai calculé le temps par moi-même
    Et c'est extrêmement long...

Discussions similaires

  1. Réponses: 1
    Dernier message: 14/12/2014, 11h26
  2. Réponses: 3
    Dernier message: 31/01/2012, 07h45
  3. [Performance Swing] Deplacement de JInternalFrame très lent
    Par Widiwi dans le forum Agents de placement/Fenêtres
    Réponses: 2
    Dernier message: 12/02/2009, 00h38
  4. [performance] Query très lent
    Par eponette dans le forum Langage SQL
    Réponses: 7
    Dernier message: 16/03/2006, 09h57
  5. [ POSTGRESQL ] Problème de performance
    Par Djouls64 dans le forum PostgreSQL
    Réponses: 6
    Dernier message: 26/05/2003, 16h18

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo