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

PHP & Base de données Discussion :

Script passe en time out [MySQL]


Sujet :

PHP & Base de données

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Mai 2004
    Messages
    803
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 803
    Par défaut Script passe en time out
    Bonjour,

    Dans un script, je lis, ligne par ligne, un fichier xls contenant 10000 lignes et une quinzaine de colonnes.

    Pour le lire toutes les lignes en affectant mes variables avec le contenu de chaque cellule et effectuer, pour chaque ligne,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    "SELECT * from cibles where tel = '" . $param[0] . "'"
    , le temps d'exécution est de 5.09149384499 micro secondes, sachant que mon champ tel est déclaré comme unique dans ma table.

    Par contre, dès que j'exécute le code suivant pour chaque ligne, je passe en time out, malgré mon set_time_limit(600); en début de script :

    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
    if($rech == "Aucun résultat")
     {
       if($erreurCible == "Enregistrement effectué")
        $erreurCampagne_cible = $campagne->determinerCible($tab['tel'], $idCampagne, "Dernier id"); //Création de l'enregistrement campagne-cible dans la table campagnes_cibles
       else
         $erreurCampagne_cible = "pas d'insertion suite à la non-insertion précédente";
     }
    else
     {
       if($erreurCible == "Modification enregistrée")
        $erreurCampagne_cible = $campagne->determinerCible($tab['tel'], $idCampagne, "tel"); //Création de l'enregistrement campagne-cible dans la table campagnes_cibles
      else
        $erreurCampagne_cible = "pas d'insertion dans la table campagnes_cibles suite à la non-mise-à-jour précédente";
     }
     
    $textErreur .= ", et dans la table campagnes_cibles, " . $erreurCampagne_cible. "\r\n";
    Voici la méthode appellé dans mon objet $campagne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public function determinerCible($telephone, $idCampagne, $maniere)
     {
       $tab[0] = $telephone;
       $tab[1] = $idCampagne;
       $tab[2] = $maniere; //L'insertion de l'id de la cible dans la table campagnes_cibles se fait soit via un select par le tel, soit par le las_insert_id() => $maniere == "tel" ou "Dernier id"
       $transaction = CtransactionsBdd::GetInstance("MYSQL", "speedcall");
       $resuReq = $transaction->insert("MYSQL_determinerCible", $tab);
     
       return $resuReq;
     }
    Voici la méthode select() appelée :

    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
    public function select($requ, $tableau)
     {
       $requete = requete($requ, $tableau);
     
       switch(self::$typeBase)
         {
          case "MYSQL":
           $result = mysql_query($requete, self::$connect);
     
           if(! $result)
            self::$erreur = "Impossible d'effectuer la sélection " . $requete;
           else
            {
              if (! mysql_num_rows($result))
               self::$erreur = "Aucun résultat";
              else
                {
                  while($row = mysql_fetch_assoc($result))
                   $resultatSelect[] = $row;
     
                  mysql_free_result($result);
                  return $resultatSelect;
                }
            }
     
         break;
       }
     }
    Et enfin, voici la fonction requete() appellée :

    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
    function requete($req, $param)
     {
       switch($req)
         {
          ...
     
          case "MYSQL_determinerCible":
            $req = "insert into campagnes_cibles set refCampagne = " . $param[1] . ", refCible = ";
     
            if($param[2] == "tel")
             $req .= "(select id from cibles where tel = '" . $param[0] . "')";
            else
             $req .= "LAST_INSERT_ID()";
     
            return $req;
            break;
          }
     }
    Donc, in fine, pour chaque ligne (il y en a 10000), je fais

    - soit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    insert into campagnes_cibles set refCampagne = idCampagne, refCible = LAST_INSERT_ID()
    - soit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    insert into campagnes_cibles set refCampagne = idCampagne, refCible = (select id from cibles where tel = 'telephone')
    Comment pourrais-je m'y prendre pour avoir un temps d'exécution raisonnable?

    Merci d'avance pour votre aide

  2. #2
    Membre éprouvé Avatar de kain_tn
    Homme Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 864
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 864
    Par défaut
    Tu pourrais peut-être générer ta requête d'INSERT puis l'exécuter une seule fois à la fin. Ton script gagnerait vraiment en rapidité.

    En gros, tes INSERT multiples deviendraient 1 INSERT: (ça doit donner un truc du genre)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    INSERT INTO campagnes (refCampagne , refCible ) 
    	VALUES (idCampagne, LAST_INSERT_ID()), 
    	(idCampagne, (select id from cibles where tel = 'telephone')), 
    	...

  3. #3
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Mai 2004
    Messages
    803
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 803
    Par défaut
    Bonjour,

    J'ai suivi tes conseils et j'ai appliqué ta méthode pour insérer mes cibles (table cibles) quand je ne dois pas les updater et insérer mes enregistrements dans ma table qui fait le lien entre mes cibles et ma campagne (table campagnes_cibles). Donc, pour ces deux cas, je construis ma requête au fur-et-à-mesure et ne les exécute alors qu'une seule fois chacune lorsque je sors de ma boucle for qui lit mon fichier xls.

    Cependant, lorsque j'effectue cela, j'ai une erreur me stipulant que l'insertion (notamment des cibles), n'a pas pu s'effectuer. En faisant passer directement ma requête

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    INSERT INTO cibles 
    (nom , tva, rc, tel, fax, email, prenomContact, nomContact, fonctionContact, telContact, faxContact, gsmContact, emailContact, commentaire) 
    VALUES 
       ('nom1', 'tva1', 'rc1', 'tel1', 'fax1', 'email1', 'prenom1', 'nomCont1', 'fonction1', 'telCont1', 'faxCont1', 'gsmCont1', 'emailCont1', 'comm1'), 
       ('nom2', 'tva2', 'rc2', 'tel2', 'fax2', 'email2', 'prenom2', 'nomCont2', 'fonction2', 'telCont2', 'faxCont2', 'gsmCont2', 'emailCont2', 'comm2'),
       ...
       et ce jusque 10000
    dans PhpMyAdmin, j'obtiens le message d'erreur suivant :

    "Fatal error: Maximum execution time of 300 seconds exceeded in C:\wamp\phpmyadmin\libraries\import\sql.php on line 87"

    Je ne trouve pas normal que pour un simple insert, même si il y en a 10000, ça prenne autant de temps.

    Qu'en penses-tu?

  4. #4
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Mai 2004
    Messages
    803
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 803
    Par défaut
    Voilà, j'ai résolu mon problème : ça provenait de la configuration de MySql et de la mémoire maximum allouée à une requête.

    J'ai donc ajouté, dans my.ini, au niveau de mysqld, "max_allowed_packet=100M" et tout est ok.

    En tout cas, merci pour ton aide et la performance que tu m'as faite gagner par la solution de l'insert mutiple.

  5. #5
    Rédacteur/Modérateur
    Avatar de andry.aime
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    8 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Ile Maurice

    Informations forums :
    Inscription : Septembre 2007
    Messages : 8 391
    Par défaut
    Bonjour,
    tu peux aussi utiliser set_ini pour ne pas éditer le fichier de configuration.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. lancer script au time out session
    Par guigo dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 7
    Dernier message: 16/06/2009, 11h26
  2. Erreur Script timed out
    Par niou142 dans le forum ASP
    Réponses: 4
    Dernier message: 14/01/2009, 11h53
  3. Intercepter le 'time out' d'un script
    Par manu_b dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 21/05/2008, 17h55
  4. [Session]maîtriser le time out de la session
    Par croquedur dans le forum Servlets/JSP
    Réponses: 8
    Dernier message: 23/10/2007, 10h57
  5. error time out expired
    Par the_new dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 30/03/2005, 13h03

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