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

SQL Oracle Discussion :

Lenteur sur une requête avec jointure


Sujet :

SQL Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Profil pro
    Inscrit en
    Février 2004
    Messages
    1 825
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 1 825
    Par défaut Lenteur sur une requête avec jointure
    Bonjour à tous,


    J'ai des clients, des dépôts, des visites.

    Un client est rattaché à un dépôt.
    Une visite est rattaché à un client et à un dépôt.

    J'ai besoin de récupérer l'ensemble des clients qui, soit son rattachés à un dépôt particulier, soit on eu une visite qui elle est rattaché à ce dépôt.

    La sélection des clients du dépôt est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SELECT * FROM TBClients WHERE CDepId=25
    La sélection des clients qui ne sont pas rattachés à ce dépôt mais qui ont eu une visite rattaché au dépôt est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    SELECT c2.ClientId FROM TBClients c2 WHERE c2.CDepId != 25 AND c2.ClientID IN
    (
        SELECT DISTINCT VClientId FROM TBVisites WHERE VDepId = 25
    )
    Ces deux requêtes sont rapides à exécuter. Par contre, j'aimerai n'en faire qu'une :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    SELECT * FROM TBClients WHERE CDepId=25 or ClientId in
    (
        SELECT DISTINCT VClientId FROM TBVisites WHERE VDepId = 25
    )
    Et là ça met 30 secondes à s'exécuter...


    Comment je peux faire pour avoir une seule requête ayant la rapidité des deux premières ?


    Merci beaucoup;

    A bientôt

  2. #2
    Expert éminent
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 818
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 818
    Billets dans le blog
    14
    Par défaut
    Une requête UNION peut-être ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    SELECT ClientId 
    FROM TBClients 
    WHERE CDepId=25
     
    UNION
     
    SELECT c2.ClientId 
    FROM TBClients c2 
    WHERE c2.CDepId != 25 AND c2.ClientID IN
    (
        SELECT DISTINCT VClientId 
        FROM TBVisites 
        WHERE VDepId = 25
    )
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole, en retraite... mais toujours Autoentrepreneur à l'occasion.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  3. #3
    Membre habitué
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    14
    Détails du profil
    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 14
    Par défaut
    Essaye plutot ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT * FROM TBClients WHERE CDepId=25 
    Union 
    SELECT * FROM TBClients C WHERE EXISTS (SELECT  1 FROM TBVISITES T
                                                                WHERE T.VClientId= C.ClientId
                                                                   AND VDepId = 25
                                                                )
    - Tu peux également utilisé une fonction
    - Il est preférable d'utiliser EXISTS au Lieu de IN

  4. #4
    Membre Expert
    Avatar de LeoAnderson
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    2 938
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 2 938
    Par défaut
    c'est un jeu de devinettes ?
    cool, j'adore ça !

    blague à part, on doit deviner les indexes ? les explains plans ? les volumétries ?

    l'optimisation de requête, ça ne se fait pas au hasard !!!

  5. #5
    Membre chevronné Avatar de miloux32
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    545
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 545
    Par défaut
    Citation Envoyé par bertrand_nt Voir le message
    Essaye plutot ceci :

    SELECT * FROM TBClients WHERE CDepId=25
    Union
    SELECT * FROM TBClients C WHERE EXISTS (SELECT 1 FROM TBVISITES T
    WHERE T.VClientId= C.ClientId
    AND VDepId = 25
    )


    - Tu peux également utilisé une fonction
    - Il est preférable d'utiliser EXISTS au Lieu de IN

    Ah non pas d'accord !!!
    On m'a toujours dit d'éviter absolument exist dans un SELECT , il est plutot concu pour un update , mais presque tous les exist dans un SELECT peuvent se remplacer par une jointure !

  6. #6
    Membre éprouvé
    Profil pro
    Inscrit en
    Février 2004
    Messages
    1 825
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 1 825
    Par défaut
    Bé en tout cas ça fonctionne bien là avec l'union.


    Merci

  7. #7
    Membre expérimenté
    Profil pro
    Inscrit en
    Août 2005
    Messages
    270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 270
    Par défaut
    Citation Envoyé par miloux32 Voir le message
    Ah non pas d'accord !!!
    On m'a toujours dit d'éviter absolument exist dans un SELECT , il est plutot concu pour un update , mais presque tous les exist dans un SELECT peuvent se remplacer par une jointure !
    Ben oui, c'est même souvent ce que fait Oracle en terme de plan d'execution ! S'il est possible de remplacer exists par une jointure, il fait "comme si". Et ce depuis toujours. Donc, ce n'est pas la peine de s'en priver.

    Et quand ce n'est pas transformable elegament avec une jointure parce que la clause exists ramene plus d'une ligne, les algorithmes utilisé par exists savent s'arreter à la première ligne trouvée, ce qui est parfaitement performant, beaucoup plus qu'un group by artificiel.

    Bref, le "on" qui t'a dit ça se prive ( et te prive) d'une fonctionnalité bien efficace et traite des problèmes simple d'une façon bien compliquée.

  8. #8
    Membre éprouvé
    Profil pro
    Inscrit en
    Février 2004
    Messages
    1 825
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 1 825
    Par défaut
    Est-ce qu'il y a des bouquins sur l'utilisation du SQL ?

    Car moi... J'y connais rien en optimisation de requête. Juste les trucs auquel j'arrive à penser, c'est mettre les conditions qui sont suceptible d'etre négative au début des critères.

    Par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SELECT * FROM TABLE WHERE CRIT1=VALEUR1 AND CRIT2=VALEUR2
    Si le critère 2 a de forte chance d'être négatif, je préfèrerai le mettre en premier.
    Je fais ça en programmation, mais je sais pas si ça fait quelque chose en SQL.

    Y'aura pas un bon bouquin qui expliquerai les bonnes pratique du SQL ?


    Et est-ce que ces bonnes pratiques sont dépendantes du SGBDR utilisé ?

    Merci,

    A bientôt

  9. #9
    Expert éminent
    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 818
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 818
    Billets dans le blog
    14
    Par défaut
    Regarde dans les tutoriels de Développez.com
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole, en retraite... mais toujours Autoentrepreneur à l'occasion.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  10. #10
    Membre expérimenté
    Profil pro
    Inscrit en
    Août 2005
    Messages
    270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 270
    Par défaut
    Citation Envoyé par mister3957 Voir le message
    Est-ce qu'il y a des bouquins sur l'utilisation du SQL ?

    Car moi... J'y connais rien en optimisation de requête. Juste les trucs auquel j'arrive à penser, c'est mettre les conditions qui sont suceptible d'etre négative au début des critères.

    Par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SELECT * FROM TABLE WHERE CRIT1=VALEUR1 AND CRIT2=VALEUR2
    Si le critère 2 a de forte chance d'être négatif, je préfèrerai le mettre en premier.
    Je fais ça en programmation, mais je sais pas si ça fait quelque chose en SQL.

    Y'aura pas un bon bouquin qui expliquerai les bonnes pratique du SQL ?


    Et est-ce que ces bonnes pratiques sont dépendantes du SGBDR utilisé ?

    Merci,

    A bientôt
    Il fut un temps ou ces considérations faisaient sens, quand l'optimiseur était basé sur des règles. L'ordre des tables dans le from et celui des conditions des clause where pouvaient changer le plan. C'est beaucoup moins vrai, voire pas vrai du tout, avec les optimiseurs statistiques.

  11. #11
    Expert éminent
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Par défaut
    Citation Envoyé par mister3957 Voir le message
    Y'aura pas un bon bouquin qui expliquerai les bonnes pratique du SQL ?
    si tu commençais par donner les infos demandées par LeoAnderson ce serait pas mal déjà

  12. #12
    Membre expérimenté
    Profil pro
    Inscrit en
    Août 2005
    Messages
    270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 270
    Par défaut
    Citation Envoyé par mister3957 Voir le message
    Est-ce qu'il y a des bouquins sur l'utilisation du SQL ?

    Car moi... J'y connais rien en optimisation de requête. Juste les trucs auquel j'arrive à penser, c'est mettre les conditions qui sont suceptible d'etre négative au début des critères.

    Par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SELECT * FROM TABLE WHERE CRIT1=VALEUR1 AND CRIT2=VALEUR2
    Si le critère 2 a de forte chance d'être négatif, je préfèrerai le mettre en premier.
    Je fais ça en programmation, mais je sais pas si ça fait quelque chose en SQL.

    Y'aura pas un bon bouquin qui expliquerai les bonnes pratique du SQL ?


    Et est-ce que ces bonnes pratiques sont dépendantes du SGBDR utilisé ?

    Merci,

    A bientôt
    Pour comprendre comment ça marche sous oracle, la doc oracle, c'est pas mal. (performance und tuning).
    En effet, les problèmes d'optimisations et les bonnes pratiques peuvent varier d'un SGBD à un autre, et même, pour un même sgbd, cela peu changer au fil des versions, soit radicalement : passage d'un optimiseur regle a un optimiseur stat, soit parce qu'il y a des améliorations.

  13. #13
    Expert éminent
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Par défaut
    Citation Envoyé par miloux32 Voir le message
    Ah non pas d'accord !!!
    On m'a toujours dit d'éviter absolument exist dans un SELECT , il est plutot concu pour un update , mais presque tous les exist dans un SELECT peuvent se remplacer par une jointure !
    en réalité il n'y a pas de règle Si la sous-requête du IN ramène peu de ligne alors faut utiliser le IN, sinon le EXISTS est souvent plus avantageux. Mais faut tester

    Et le IN comporte un piége puisque les valeurs NULL sont exclues

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

Discussions similaires

  1. Aide sur une requête avec jointure et LIMIT 1
    Par mister3957 dans le forum Langage SQL
    Réponses: 7
    Dernier message: 28/06/2013, 20h17
  2. Réponses: 16
    Dernier message: 20/01/2011, 12h45
  3. Besoin aide sur une requête avec jointure
    Par PoichOU dans le forum Requêtes
    Réponses: 3
    Dernier message: 31/08/2010, 18h32
  4. Aide sur une requête avec jointure..
    Par WeDgEMasTeR dans le forum Requêtes
    Réponses: 7
    Dernier message: 10/11/2009, 18h09
  5. optimisation d'une requête avec jointure
    Par champijulie dans le forum PostgreSQL
    Réponses: 8
    Dernier message: 07/07/2005, 09h45

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