Partage
  • Partager sur Facebook
  • Partager sur Twitter

doublon mysql lenteur requete

    29 novembre 2020 à 18:34:10

    BOnjour

    soit une table avec bcp de champs.( 50 )

    je souhaite dedoublonner ma base en recherchant les tuples ayant mêmes :  nom prenom et spécialité.

    j'ai la requête qui marche. : (pompé qq part :-) )

    SELECT
        DISTINCT *
    FROM
        table AS t1
    WHERE EXISTS
        (
        SELECT
            *
        FROM
            table AS t2
        WHERE
            t1.id <> t2.id AND t1.nom = t2.nom AND t1.prenom = t2.prenom AND t1.specialite = t2.specialite
    ) AND t1.nom <> 'XX' AND id_user = '224'
    ORDER BY
        nom,
        prenom,
        specialite ASC

     mon soucis est la LENTEUR ++ ( >10-15 secondes ) pour trouver les fiches qui ont mêmes nom prenom et spécialité  alors que ma base ne comporte que 6500 fiches.

    Si je met seulement qq champs à la place de " SELECT *" dans la partie WHERE EXISTS ( SELECT * ... cela ne change RIEN.

    2 questions : 

    -  comment accélérer la recherche de doublon sur 3 CHAMPS ?

    -  comment avoir le nbre de fiches retenues par cette requête ?  un Count(*) ne marche pas

    merci

    • Partager sur Facebook
    • Partager sur Twitter
      30 novembre 2020 à 9:24:26

      Bonjour,

      Pour commencer on peut travailler avec les jointures, ce devrait être plus rapide :

      SELECT
      	T1.id AS id1,
      	T2.id AS id2
      FROM
      	matable T1
      		INNER JOIN matable T2
      			ON T1.id < T2.id -- id différents
      			AND T1.nom = T2.nom -- même nom
      			AND T1.prenom = T2.prenom -- même prénom
      			AND T1.specialite = T2.specialite -- même spécialité

      Cela devrait résoudre le problème de lenteur.

      Ensuite pour savoir le nombre correspondant, la première solution est dans le retour de la console ou de ton interface de gestion (PHPMyAdmin par exemple) qui le plus souvent donne le nombre de résultats retournés après exécution d'une requête.

      Sinon, tu peux faire le compte dans ton programme (soit dans une boucle si tu travailles avec fetch, soit avec un count si tu travailles avec fetchAll).

      Enfin, tu peux faire une deuxième requête qui fait seulement le compte :

      SELECT COUNT(*) AS nb_doublons
      FROM
      	matable T1
      		INNER JOIN matable T2
      			ON T1.id < T2.id -- id différents
      			AND T1.nom = T2.nom -- même nom
      			AND T1.prenom = T2.prenom -- même prénom
      			AND T1.specialite = T2.specialite -- même spécialité

      Ou pour compter par id :

      SELECT
      	T1.id,
      	COUNT(*) AS nb_doublons
      FROM
      	matable T1
      		INNER JOIN matable T2
      			ON T1.id < T2.id -- id différents
      			AND T1.nom = T2.nom -- même nom
      			AND T1.prenom = T2.prenom -- même prénom
      			AND T1.specialite = T2.specialite -- même spécialité
      GROUP BY T1.id
      • Partager sur Facebook
      • Partager sur Twitter
      Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
        30 novembre 2020 à 10:01:56

        bonjour 

        Merci d'avoir pris le temps de me répondre.

        J'ai appliqué ta première procédure ... et là ... j'ai 22527 réponses !!! sur ma base qui contient 6500 tuples. Doit y a voir un schmilblick !

        Mon but est de retrouver les doublons ( ou triplons ... ) .

        Ne devraient donc être retenus que les personnes qui ont même nom même prenom et même spécialité 

        Cela semble pourtant être le cas ... car en ajoutant des champs nom prenom spécialité, cp ville dans la requête je vois bien que les fiches retenues sont bonnes ...mais pourquoi en avoir > 22000 ? -  le temps de recherche s'en trouve LONG là aussi.

        • Partager sur Facebook
        • Partager sur Twitter
          30 novembre 2020 à 10:17:51

          french-petzouille a écrit:

          ta première procédure ... et là ... j'ai 22527 réponses 

          Peux-tu poster la requête exacte qui te retourne les 22527 résultats ?

          french-petzouille a écrit:

          mais pourquoi en avoir > 22000 ?

          Imaginons que l'id 1,2,3 et 4 sont des lignes identiques. La requête va te remonter chaque couple identique, ici 1/2, 1/3, 1/4, 2/3, 2/4, 3/4 (6 lignes).

          Avec cet exemple, la deuxième requête ne devrait te ressortir que 3 lignes : 1 (pour 4), 2 (pour 3), 3 (pour 2).

          Si l'on garde cet exemple, que souhaiterais obtenir comme retour ?

          Pour accélérer la requête tu peux mettre un index sur les trois colonnes en question (nom, prénom, spécialité), et t'assurer qu'il y en a bien un sur la colonne id.

          -
          Edité par Benzouye 30 novembre 2020 à 10:19:15

          • Partager sur Facebook
          • Partager sur Twitter
          Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
            30 novembre 2020 à 10:45:08

            Ma requête qui retourne > 20 000 LIGNES
            SELECT
                T1.id AS id1,T1.nom, T1.prenom,T1.specialite,T1.email, T1.rpps,
                T2.id AS id2,T2.nom, T2.prenom,T2.specialite,T2.email, T2.rpps
            FROM
                CVDL T1
                    INNER JOIN CVDL T2
                        ON T1.id < T2.id 
                        AND T1.nom = T2.nom 
                        AND T1.prenom = T2.prenom 
                        AND T1.specialite = T2.specialite  
            ORDER BY `T1`.`nom` ASC

            si j'affine TA requête en mettant une condition de plus  j'ai 658 LIGNES  : 
            SELECT
                T1.id AS id1,T1.nom, T1.prenom,T1.specialite,T1.email, T1.rpps,
                T2.id AS id2,T2.nom, T2.prenom,T2.specialite,T2.email, T2.rpps
            FROM
                csmf_medecinsCVDL T1
                    INNER JOIN csmf_medecinsCVDL T2
                        ON T1.id < T2.id 
                        AND T1.nom = T2.nom 
                        AND T1.prenom = T2.prenom 
                        AND T1.specialite = T2.specialite  
                        AND T1.nom<>'XX' AND T1.id_user='224' /// <--- 
            ORDER BY `T1`.`nom` ASC
            EN PRENANT MA REQUETE D'ORIGINE ... celle pompée sur un site pour trouver des doublons j'ai :  1295 LIGNES
            SELECT DISTINCT
                *
            FROM
                CVDL AS t1
            WHERE EXISTS
                (
                SELECT
                    *
                FROM
                    CVDL AS t2
                WHERE
                    t1.id <> t2.id AND t1.nom = t2.nom AND t1.prenom = t2.prenom AND t1.specialite = t2.specialite
            ) AND t1.nom <> 'XX' AND id_user = '224'
            ORDER BY
                nom,
                prenom,
                specialite ASC
             658 versus 1295 ! les 2 requêtes ne trouvent pas le même nombre.
            tu me dis 
            Pour accélérer la requête tu peux mettre un index sur les trois colonnes en question (nom, prénom, spécialité), et t'assurer qu'il y en a bien un sur la colonne id.
            je fais comment ?
            merci
            • Partager sur Facebook
            • Partager sur Twitter
              30 novembre 2020 à 12:06:36

              Ta requête a une condition T1.id <> T2.id ce qui fait qu'elle ressort le couple 1/2 et le couple 2/1 alors que la mienne non. Cela explique une partie de l'écart ... 658 x 2 = 1316 ... mais je ne saurais expliquer l'écart restant de 21 (1316 - 1295) ...

              Pour mettre les index :

              ALTER TABLE CVDL
              	ADD INDEX( nom ),
              	ADD INDEX( prenom ),
              	ADD INDEX( specialite );

              Je vais reposer ma question :

              Benzouye a écrit:

              Imaginons que l'id 1,2,3 et 4 sont des lignes identiques.

              [...]

              Si l'on garde cet exemple, que souhaiterais obtenir comme retour ?

              Par exemple, si ton besoin c'est de ressortir seulement les couples nom/prénom/spécialité avec le nombre d'apparition pour chacun, alors :

              SELECT
              	T1.nom,
              	T1.prenom,
              	T1.specialite,
              	COUNT(*) AS nb_doublons,
              	GROUP_CONCAT( T2.id ) AS ids
              FROM
                  CVDL T1
                      INNER JOIN CVDL T2
                          ON T1.id < T2.id
                          AND T1.nom = T2.nom
                          AND T1.prenom = T2.prenom
                          AND T1.specialite = T2.specialite
              GROUP BY
              	T1.nom,
              	T1.prenom,
              	T1.specialite

              -
              Edité par Benzouye 30 novembre 2020 à 12:51:31

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

              doublon mysql lenteur requete

              × 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