Partage
  • Partager sur Facebook
  • Partager sur Twitter

PDO UPDATE trop long à s'exécuter

    10 mai 2022 à 14:28:41

    Besoin d'aide ! s'il vous plaît, à propos de cette mise à jour PDO qui fonctionne mais qui prend trop de temps à s'exécuter (presque 10 secondes)

    // le $_POST suivant reçoit 365 valeurs envoyées par les 365 inputs d'un formulaire

    $k = $_POST['k'];

    // ici je fais un UPDATE des 365 valeurs de la colonne2 de maTable
    // ça marche mais la requête prend trop de temps à s'exécuter

    $sql = "UPDATE maTable SET colonne2=: column2 WHERE id=:id";
    $stmt = $conn->prepare($sql);

    for ($i = 1; $i <= 365; $i++) {
       $id[$i] = $i;
       $n = $i-1;
       $stmt->bindParam(': colonne2', $k[$n], PDO::PARAM_STR);
       $stmt->bindParam(':id', $id[$i], PDO::PARAM_INT);
       $stmt->execute();
    }


    -
    Edité par BillTop 10 mai 2022 à 15:50:30

    • Partager sur Facebook
    • Partager sur Twitter
      10 mai 2022 à 15:58:21

      Bonjour,

      BillTop a écrit:

      365 valeurs envoyées

      Donc tu exécutes 365 requêtes UPDATE ...

      Plusieurs choses peuvent déterminer le temps de réponse.

      La première, c'est l'indexation de la colonne id. Vérifies que cette colonne possède bien un INDEX, on pourrait espérer que ce soit la clé primaire non ?

      Ensuite, le temps de réponse de ton serveur. Si tu n'exécutes qu'un seul UPDATE, combien de temps le script met-il à s'exécuter ?

      • Partager sur Facebook
      • Partager sur Twitter
      Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
        10 mai 2022 à 21:31:31

        Bonjour,

        Merci pour ta réponse.

        Oui, il y a bien 365 inputs dans le formulaire.

        La colonne id est indexée en clé primaire avec une numérotation unique pour chaque ligne de 1 à 365, pour gérer les jours l'année 2022.

        La colonne2 stocke la valeur de chacun des 365 inputs selon le choix de celui qui met à jour le planning via le formulaire.

        Tu dis que j’exécute donc 365 requêtes, je ne sais quoi répondre...
        il semble que oui, vu la lenteur extrême de l'exécution.

        Cependant, j'ai cru qu'en plaçant la requête ainsi que sa préparation en dehors de la boucle For, cela pourrait résoudre le problème.

        En réponse à ta dernière question :
        si je n'exécute qu'un seul UPDATE le serveur local situé sur phpMyAdmin met environ 0,7 seconde avant de recharger la page du formulaire.

        Merci pour votre aide,
        Bonne soirée à tous...

        • Partager sur Facebook
        • Partager sur Twitter
          10 mai 2022 à 23:17:38

          1. Désactiver l'émulation ($conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);)
          2. Revoir ton usage de bindParam, il est mal utilisé, comme un bindValue :
          $conn = new PDO(/* ... */);
          $conn-&gt;setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);
          
          $stmt = $conn-&gt;prepare('UPDATE maTable SET colonne2=:column2 WHERE id=:id');
          $stmt-&gt;bindParam('column2', $k);
          $stmt-&gt;bindParam('id', $id, PDO::PARAM_INT);
          foreach ($_POST['k] as $id =&gt; $k) {
              $stmt-&gt;execute();
          }
          

          Tant qu'à faire, générer des input par name="k[<?= $id ?>]" et non name="k[]" tout court pour être sûr que ça correspond au lieu de présumer que ces ids commencent à 1, sont contigus et toujours par ordre croissant.

          Ca ne fera pas des miracles mais c'est le seul moyen de réellement optimiser sans générer une requête UPDATE unique (une CTE depuis MySQL 8 ou à coups de VALUES( ... ) dans une sous-requête ?).

          -
          Edité par julp 10 mai 2022 à 23:28:23

          • Partager sur Facebook
          • Partager sur Twitter
            10 mai 2022 à 23:17:53

            O.7s me paraît beaucoup trop.

            J'ai fait un test en local avec un script PHP équivalent pour 1000 iterations et il passe en moins de 2s...

            Je quppose que le problème vient du serveur, donc de ton poste local...

            Y a t'il d'autres applicatifs sollicitant en même temps ?

            -
            Edité par Benzouye 10 mai 2022 à 23:18:24

            • Partager sur Facebook
            • Partager sur Twitter
            Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
              14 mai 2022 à 11:10:44

              Bonjour à tous,

              En réponse à Julp,
              les ids commencent à 1, sont contigus et toujours par ordre croissant car il s'agit d'une table qui ne reçoit aucun INSERT. Cette table est composée de 365 lignes correspondant aux 365 jours de l'année 2022, effectivement, je ne l'avais pas dit dans mon premier message.

              Autre précision importante :
              les 'UPDATE' ne se feront que par choix binaire (du style 0 ou 1). La charte graphique de la page du formulaire est construite pour que l'utilisateur puisse cliquer sur les inputs en forme de petits carrés (aux couleurs de fond rouge ou vert) avec un ONCLICK qui lance une fonction JavaScript en mode toggle qui fera basculer (entre le rouge ou le vert) la couleur de fond de l'input selon la présence ou l'absence signalée par l'utilisateur pour tel ou tel autre jour de l'année en cours…

              Voilà, cette fois j'ai tout dit !

              Pour le moment la requête fonctionne,
              seul un petit souci de lenteur se pose en faisant des essais en local (avec php 5.6 et MySQL 5.7) sur UwAmp associé à PHPMyAdmin.

              Comme le suppose Benzouye,
              le problème vient peut-être du serveur, donc de mon poste local...
              cependant, il n'y a pas à ma connaissance d'autres applicatifs qui sollicitent en même temps ce serveur local.
              La réponse sera donnée lors du premier essais sur le serveur externe de Free dont voici la version: PHP Version 5.1.3RC4-dev, affichée suite à l'exécution de phpinfo();

              Merci encore à vous deux pour vos conseils !

              Pour finir, une petite question concernant le fichier .htaccess situé à la racine du serveur Free pages perso :
              la première ligne comporte la mention:

              php 1

              Sachant que le site, déjà présent sur ce serveur, a été conçu à l'époque d'avant php 5.6,
              y aurait-ilun risque à modifier le .htaccess en remplaçant 'php 1' par le code suivant :

              <IfDefine Free>
              php56 1
              </IfDefine>

              Question liée :
              Le PDO est-il actuellement pris en charge pour les pages perso de Free ?

              • Partager sur Facebook
              • Partager sur Twitter
                14 mai 2022 à 11:23:41

                Si j'ai bonne mémoire seule leur version PHP 5.6 dispose du driver mysql pour PDO, mais c'est facile à vérifier, cette information figure dans la sortie du phpinfo justement.

                > y aurait-ilun risque à modifier le .htaccess en remplaçant 'php 1' par le code suivant

                Si c'est vraiment du vieux code, tu risques potentiellement de casser certaines choses.

                -
                Edité par julp 14 mai 2022 à 11:24:28

                • Partager sur Facebook
                • Partager sur Twitter
                  14 mai 2022 à 12:11:05

                  Merci,

                  Aurais-tu + d'info à propos de sqlite ?

                  voici un imprime-écran du phpinfo

                  • Partager sur Facebook
                  • Partager sur Twitter
                    14 mai 2022 à 13:03:39

                    > Aurais-tu + d'info à propos de sqlite ?

                    C'est-à-dire ? Parce que ce n'est pas très précis comme demande.

                    Donc un screen du phpinfo de la version 5.1.3 qui montre, comme je le disais, que le pilote mysql n'est pas disponible ? Tu as essayé de basculer sur la 5.6 ? (c'est l'occasion de voir si le site déjà en place a quelques "incompatibilités")

                    • Partager sur Facebook
                    • Partager sur Twitter
                      16 mai 2022 à 14:19:43

                      Dans ton code initial, 2 variables inutiles dans ta boucle $id et $n, utilise directement $i et $i-1 (ça ne fera pas gagner de temps en principe, mais si on peux s'éviter des choses inutiles)
                      • Partager sur Facebook
                      • Partager sur Twitter
                        18 mai 2022 à 17:46:27

                        Bonjour umfred,

                        C'est fait, j'ai mis $i et $i-1, c'est vrai que c'est inutile de les stocker dans une variable supplémentaire.

                        Merci pour ton aide.

                        • Partager sur Facebook
                        • Partager sur Twitter

                        PDO UPDATE trop long à s'exécuter

                        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                        • Editeur
                        • Markdown