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 SQL Discussion :

optimisation requete de doublons


Sujet :

Langage SQL

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    57
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 57
    Points : 43
    Points
    43
    Par défaut optimisation requete de doublons
    Bonjour

    J'ai écris une requete qui doit me retourner un résultat sans doublons mais elle est très lent à s'éxécuter alors je voudrais votre avis pour la modifier.
    Voici la table à interroger
    ID PRENOM NOM

    1 ALBERT DUPONT
    2 PIERRE DURAND
    3 ALBERT DUPONT
    4 GEORGES DUPUIS

    je ne veux pas supprimer les doublons, je veux juste n'afficher qu'une seule fois les doublons relatifs, pour obtenir dans cet exemple :

    ID PRENOM NOM

    1 ALBERT DUPONT
    2 PIERRE DURAND
    4 GEORGES DUPUIS

    ma requete
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT T1.* 
    FROM TABLE T1 
    WHERE T1.ID=
     (SELECT MIN(T2.ID) 
      WHERE T1.PRENOM=T2.PRENOM 
        AND T1.NOM=T2.NOM
     )
    cette requete fonctionne mais est tres lente car en réalité, TABLE est issue d'une autre requete (simple select).

    Un idée pour optimiser ?

  2. #2
    Membre confirmé Avatar de getz85
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2008
    Messages
    423
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2008
    Messages : 423
    Points : 462
    Points
    462
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SELECT DISTINCT * FROM table

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    424
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 424
    Points : 382
    Points
    382
    Par défaut
    lol, marrant sa requête

    ou s'il à d'autre champs dans sa table
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT DISTINCT ID,PRENOM,NOM FROM TABLE

  4. #4
    Membre émérite

    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 683
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 683
    Points : 2 579
    Points
    2 579
    Par défaut
    En utilisant ou vous n'éliminerez jamais de ligne puisque l'identifiant est unique. C'est le couple [Nom ,Prénom] qui peut présenter des doublons.

  5. #5
    Membre du Club
    Profil pro
    Architecte logiciel
    Inscrit en
    Janvier 2006
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Architecte logiciel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2006
    Messages : 28
    Points : 48
    Points
    48
    Par défaut
    sauf que le distinct sur tout les champs, ou * ca renvera tous les tuples hein.

    s'il y a besoin de remonter le premier dans l'ordre des id, il vaut mieux utiliser une fonction de partition ( base compatible sql2003 ).

    par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    select t.id, t.nom, t.prenom
    FROM (
        Select row_number() over (partition by p.nom, p.prenom order by p.id asc) row, p.id, p.nom, p.prenom
       From dbo.PERSONNE  as p
    ) as t
    where t.row = 1
    sinon ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SELECT ID, NOM PRENOM from personne p1 where not exists ( select 1 from personne p2 where p2.nom = p1.nom AND p2.prenom = p1.prenom and p2.id < p1.id)

  6. #6
    Membre habitué
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 142
    Points : 185
    Points
    185
    Par défaut
    Malheureusement ces 2 requêtes ne vont pas puisque le champs ID est différent pour chacun des 2 "ALBERT DUPONT".
    Les 2 enregistrements seront donc retournés à moins de ne pas sélectionner l'ID dans la requête...

    edit : grillaid

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    424
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 424
    Points : 382
    Points
    382
    Par défaut
    Me parais bien compliqué la solution de fallo

    Aller moi je dirais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT id,nom,prenom FROM table GROUP BY nom,prenom
    id n'étant pas dans le GROUP BY il prendras le premier qu'il rencontre(indéfini), s'il veux le premier dans l'ordre numérique

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT MIN(id),nom,prenom FROM table GROUP BY nom,prenom
    Mais après tout je suis pas sur qu'il ai besoin de l'id

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    424
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 424
    Points : 382
    Points
    382
    Par défaut
    S'il n'en a pas besoin, ce que je pense

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT DISTINCT nom,prenom FROM TABLE

  9. #9
    Membre du Club
    Profil pro
    Architecte logiciel
    Inscrit en
    Janvier 2006
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Architecte logiciel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2006
    Messages : 28
    Points : 48
    Points
    48
    Par défaut
    evidement le group by avec un min sur la colone id est de loins la meilleure dans ce cas, oui ( désolé ).

    par contre le group by sans mettre tout les champs du select, c'est interdit.

    s'il y a d'autres champs que ces trois la, et/ou un besoin de faire une jointure avec d'autres tables une de mes solutions compliquée seront alors surement necessaire.

  10. #10
    Membre habitué
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 142
    Points : 185
    Points
    185
    Par défaut
    Citation Envoyé par Eric93 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT id,nom,prenom FROM table GROUP BY nom,prenom
    Attention, cette requête ne passe même pas sous SQL Server par exemple (alors qu'elle passe en MySQL, ça dépend donc de la BDD).
    Par contre ta 2ème proposition avec le MIN me parait effectivement la solution la + simple s'il veut récupérer un ID !

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    424
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 424
    Points : 382
    Points
    382
    Par défaut
    Effectivement ca passe en MySQL de mettre un champ qui n'appartient pas au GROUP BY, je l'ai appris recement, et encore je crois que c'est pas dans toute les version.

    Ca ramène une des valeur de id, mais laquelle, j'en sais trop rien

    Mais fonctionnellement je vois pas l'interet de récupérer un id parmis n, enfin ya peut-être une raison

  12. #12
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    424
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 424
    Points : 382
    Points
    382
    Par défaut
    S'il n'as pas besoin de l'id
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT DISTINCT nom,prenom from table
    donne le même résultat que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT nom,prenom FROM table GROUP BY nom,prenom
    mais le DISTINCT est beaucoup plus performant que le GROUP BY car dans le GROUP BY il selectionne d'abord toute la table avant de regrouper, il s'effectue après le SELECT

  13. #13
    Membre émérite

    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 683
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 683
    Points : 2 579
    Points
    2 579
    Par défaut
    Sauf que ce genre de requête ramène les toutes les couples [NOM,PRENOM] distincts et non pas les couples qui ont des doublons.

    Si on ne veut que les couples [NOM,PRENOM] qui sont en double (ou plus) dans la table, un simple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT NOM, PRENOM, COUNT(ID)
    FROM T_TABLE
    GROUP BY NOM, PRENOM 
    HAVING COUNT(ID) > 1
    donne le résultat.

  14. #14
    Membre habitué
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 142
    Points : 185
    Points
    185
    Par défaut
    Eric93 >> Je crois que MySQL retourne tout simplement la 1ère veleur rencontrée, donc ici l'ID du 1er enregistrement correspondant rencontré. Enfin à confirmer.
    Par contre je suis étonné que le DISTINCT soit plus rapide que le GROUP BY. En effet, lors d'une requête avec un DISTINCT, TOUS les enregistrements correspondant à la requête sont sélectionnés, et ce n'est qu'ENSUITE que le moteur de la BDD vérifie s'il y a des doublons, et le cas échéant supprime les enregistrements superflus du jeu de résultat.
    Voila d'ailleurs pourquoi il faut utiliser le DISTINCT que si c'est réellement nécessaire, sinon des tests inutiles sont réalisés...

  15. #15
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    424
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 424
    Points : 382
    Points
    382
    Par défaut
    TOUS les enregistrements correspondant à la requête sont sélectionnés, et ce n'est qu'ENSUITE que le moteur de la BDD vérifie s'il y a des doublons, et le cas échéant supprime les enregistrements superflus du jeu de résultat.
    Non c'est le contraire, c'est le GROUP BY qui est traité après le SELECT, c'est dailleur visible dans la syntaxe

    Je crois que MySQL retourne tout simplement la 1ère veleur rencontrée, donc ici l'ID du 1er enregistrement correspondant rencontré
    C'est vrai, mais le premier rencontré n'est pas forcément le premier dans l'ordre numérique, tout dépend de l'ordre des insertions

  16. #16
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    424
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 424
    Points : 382
    Points
    382
    Par défaut
    LoL, j'ai l'impression que ce post n'interesse pas son auteur, mdr

  17. #17
    Membre émérite

    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 683
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 683
    Points : 2 579
    Points
    2 579
    Par défaut
    Citation Envoyé par Eric93 Voir le message
    Non c'est le contraire, c'est le GROUP BY qui est traité après le SELECT, c'est dailleur visible dans la syntaxe
    Je suis désolé de vous contredire mais l'ordre des mots clé dans le SQL n'a aucun lien avec l'ordre du plan d'execution qui va traiter physiquement les données.

    Affichez le plan d'execution de vos requêtes si votre SGBD le permet et vous pourrez réellement voir comment le moteur procède.

  18. #18
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    424
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 424
    Points : 382
    Points
    382
    Par défaut
    Je vais me renseigné, mais je suis presque sur que le GROUP BY s'effectue après le SELECT contrairement au DISTINCT qui s'effectue directement (comment ? je sais pas trop).

    Je suis un ancien de DB2, l'ancètre de toute les SGBD relationnel et j'ai toujours appris ca.

    Maintenant je dis pas que l'ordre dans la syntaxe influence le comportement, mais je dis que la syntaxe des 2 ordres exprime clairement dans quel ordre ca s'effectue.

    C'est par pour rien que le mot DISTINCT est derière le SELECT et le GROUP BY après le FROM.

  19. #19
    Membre habitué
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 142
    Points : 185
    Points
    185
    Par défaut
    Désolé mais je ne suis pas convaincu...
    J'ai toujours appris par exemple, qu'il valait mieux réaliser un UNION ALL entre 2 requêtes plutôt qu'un UNION si on était sur de ne pas avoir de résultats identiques ramenés par les 2.
    Tout simplement car un UNION ALL va récupérer tous les résultats des 2 requêtes, doublons ou pas, alors qu'un UNION agit de manière ensembliste, et agit donc comme un DISTINCT sur les résultats des 2 requêtes, ce qui grêve les perfs car les doublons sont éliminés APRES que le moteur ait récupéré tous les résultats.

  20. #20
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    424
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 424
    Points : 382
    Points
    382
    Par défaut
    Par exemple dans une requête du type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT .... FROM table WHERE ... GROUP BY ... HAVING ...
    SQL exécute d'abord
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT .... FROM table WHERE ...
    Puis sur le résultat il exécute
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    GROUP BY ... HAVING ...
    HAVING étant l'équivalent du WHERE mais pour le GROUP BY

    Si par exemple on fait (sans interet, c'est pour l'exemple) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT .... FROM table WHERE ... HAVING ...
    HAVING sans GROUP BY, les conditions du HAVING sont alors combiné avec les conditions du WHERE

    Si t'es toujours pas convaincu je vais chercher dans la doc d'autres arguments

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. [doublon topic, FERMETURE] Optimisation requete 3 tables
    Par arobaskette dans le forum Langage SQL
    Réponses: 1
    Dernier message: 02/07/2013, 09h18
  2. optimisation requetes (besoin de votre avis)
    Par seb92 dans le forum Requêtes
    Réponses: 2
    Dernier message: 21/12/2004, 11h27
  3. [PL/SQL] Optimisation requete SQL
    Par CDRIK dans le forum Langage SQL
    Réponses: 3
    Dernier message: 14/10/2004, 09h52
  4. [SYBASE] optimisation requete UPDATE
    Par metheorn dans le forum Sybase
    Réponses: 8
    Dernier message: 24/05/2004, 17h01
  5. Optimisation requetes SQL
    Par joel90 dans le forum Administration
    Réponses: 18
    Dernier message: 15/05/2004, 21h45

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