Partage
  • Partager sur Facebook
  • Partager sur Twitter

requête d'insertion prend trop de temps

après exécution d'une fonction Python toute requête d'insertion coince

Sujet résolu
    14 janvier 2019 à 21:34:03

    Bonjour,

    Je travaille sur un projet utilisant MySQL 8.0, Python 3.5 et un connecteur, et ça fait des heures que je galère avec une bogue. Je sais que je ferais bien de partager mon code (ou plutôt mes codes) avec vous, mais celui-ci est un peu illisible, (d'autant plus que je l'ai écrit en néerlandais).

    Permettez-moi donc de vous expliquer où j'en suis sans prêter d'attention au code pour l'instant. J'ai écrit une fonction en Python qui insère des lignes  dans une de mes tables grâce à une boucle. Or, quand je l'exécute je constate que rien ne s'est ajouté à ma table. Il devient par ailleurs tout d'un coup impossible d'insérer de nouvelles données dans la table : les requêtes d'insertion prennent tellement de temps qu'elles sont interrompues avant d'avoir été exécuté. (Ça m'affiche ERROR 1205 (HY000): Lock wait timeout exceeded;... )

    J'ai vu sur Stack Overflow qu'il y a eu des gens avec des bogues semblables, et dans leur cas le fait de "tuer" des processus dans la Processlist a parfois aidé.

    Or, dans mon cas chaque processus que j'essaie de "tuer" est remplacé par un nouveau processus. Alors, je ne peux rien faire d'autre que d'attendre pour pouvoir insérer des données.

    Qu'est-ce que vous en pensez ? Avez-vous une idée d'une façon de résoudre mon problème ? Je vous en serais reconnaissant.

    -
    Edité par KoenvanDuin 15 janvier 2019 à 7:41:43

    • Partager sur Facebook
    • Partager sur Twitter
      14 janvier 2019 à 22:24:51

      Bonjour,

      C'est plus un problème Python et je ne suis vraiment pas un spécialiste. Mais déjà, est-ce que tu utilises une requête préparée ?

      Ca te ferait déjà gagner beaucoup de ressources par rapport à une boucle sur une requête en dur.

      • Partager sur Facebook
      • Partager sur Twitter
        15 janvier 2019 à 7:35:34

        Bonjour, 

        Merci pour votre réponse. Non, je n'ai pas utilisé de requête préparée. La table n'ayant que deux colonnes, je me suis dit, que le fait d'utiliser des requêtes préparées n'apporterait pas grand-chose. Je vais lire la documentation de MySQL pour savoir si j'ai eu raison, ou si je ne me suis pas suffisamment renseigné.

        Mais la fonction à cause de laquelle les requêtes d'insertion ne marchent plus n'essaie d'enregistrer qu'une centaine de lignes dans une table de deux colonnes.  Ça ne peut quand même pas être une charge si pesante ?

        Je comprends que m'a question n'est pas tout à fait à sa place ici étant donné que ce forum est uniquement consacré à MySQL. Cela dit, je ne pense pas que ça ait été mieux de l'avoir posé sur le forum de Python.

        Je vais partager un morceau de mon code avec vous et surtout avec les lecteurs à venir. Peut-être ça aidera tout de même.

        -
        Edité par KoenvanDuin 15 janvier 2019 à 7:37:06

        • Partager sur Facebook
        • Partager sur Twitter
          15 janvier 2019 à 8:48:55

          En effet ça paraît peu probable que ce soit trop lourd.

          Mais si tu limites ta boucle à un tour, ça fonctionne ou pas ?

          • Partager sur Facebook
          • Partager sur Twitter
            15 janvier 2019 à 10:56:51

            Bonjour,

            Peux-tu nous donner le nombre d'itération de la boucle ?

            Es-tu sûr que ce nombre est effectivement pris en compte ?

            Au lieu de faire x requêtes du type :

            INSERT INTO matable ( colonne1, colonne2 )
            VALUES ( 'valeur1', 'valeur2' );

            Tu peux faire une seule requête du type :

            INSERT INTO matable ( colonne1, colonne2 )
            VALUES
            ( 'valeur1', 'valeur2' ),
            ( 'valeur1', 'valeur2' ),
            ( 'valeur1', 'valeur2' ),
            ...
            ( 'valeur1', 'valeur2' ),
            ( 'valeur1', 'valeur2' );
            • Partager sur Facebook
            • Partager sur Twitter
            Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
              15 janvier 2019 à 11:45:02

              Bonjour,

              Je me suis rendu compte qu'il n'y a même pas une centaine de requêtes à exécuter: ce sont seulement 27 requêtes. Je vais regarder ce qui se passe si j'insère tous les enregistrements avec une seule requête, mais permettez-moi d'abord de partager un morceau de mon code.

              MaTable contient sert à indiquer quelles légumes sont disponible en quels mois. Le dictionnaire que je récupère contient des paires (mois: liste de légumes dispos).

              def remplisMaTable():
                  cursor.execute("DELETE FROM MaTable;") # On efface le contenu déjà présent de la table.
                  dico = dicoDeDonnees() # recupère un dico sur lequel je ne veux pas trop m'attarder.
                  nomsLegumes = getColonne("nom","Legumes")
                  nomsMois = getColonne("nom","Mois")
                  debutDeRequete = "INSERT INTO MaTable (legume_id, mois_id) VALUES "
                  for nomLegume in nomsLegumes:
                      for nomMois in nomsMois:
                          if nomMois in list(dico.keys()):
                              if nomLegume in wb[nomMois]:
                                  cursor.execute("SELECT id FROM Legumes WHERE nom = \"{}\";".format(nomLegume))
                                  idLegume = cursor.fetchone()[0]
                                  cursor.execute("SELECT id FROM Mois WHERE nom = \"{}\";".format(nomMois))
                                  idMois = cursor.fetchone()[0]
                                  requete = debutDeRequete + "({},{});".format(idLegume,idMois)
                                  cursor.execute(requete)

              Il me semble d'ailleurs que même la requête "DELETE FROM MaTable;" n'a pas marché. Peut-être ça veut dire que je me suis trompé de forum comme Philodick l'a dit au début. Si vous ne voyez pas d'ou vient le dysfonctionnement du code je vais fouiner dans la documentation de MySQL et je laisse ce projet de côté pour le moment. En tout cas merci à vous de m'avoir essayé de m'aider. 

              -
              Edité par KoenvanDuin 15 janvier 2019 à 12:05:20

              • Partager sur Facebook
              • Partager sur Twitter
                15 janvier 2019 à 12:06:39

                En regardant ton code, je pense que tu peux tout faire en une seule requête ...

                INSERT INTO matable( legume_id, mois_id )
                	SELECT L.id, M.id
                	FROM Legumes L CROSS JOIN Mois M
                	WHERE
                		M.nom IN (...)
                		AND L.nom IN (...);

                Selon la taille des tableaux wb et dico, les points de suspensions seront à remplacer par la liste des valeurs ...

                -
                Edité par Benzouye 15 janvier 2019 à 12:07:37

                • Partager sur Facebook
                • Partager sur Twitter
                Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
                  16 janvier 2019 à 8:11:52

                  Me revoici !

                  Je crois comprendre ce qui se passait maintenant. Par défaut, il faut que les commits soient faits explicitement, ce que j'avais oublié. Je suis un peu honteux d'avoir fait appel à vous pour si peu. Je suis désolé de vous avoir fait perdre votre temps. En tout cas je vais utiliser les requêtes que Benzouye m'a données, ça pourrait rendre mon code beaucoup plus lisible.

                  Merci !

                  • Partager sur Facebook
                  • Partager sur Twitter

                  requête d'insertion prend trop de temps

                  × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                  × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                  • Editeur
                  • Markdown