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

Oracle Discussion :

Ne choisir QUE les lignes qui ont ce critere


Sujet :

Oracle

  1. #1
    Futur Membre du Club
    Inscrit en
    Avril 2004
    Messages
    14
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Avril 2004
    Messages : 14
    Points : 9
    Points
    9
    Par défaut Ne choisir QUE les lignes qui ont ce critere
    Bonjour
    Alors voila pour resumé mon problème, j'ai 2 tables.

    Une table A avec la clé primaire id_A
    et une table B qui contient un champs champ_B et id_A

    Les tables A et B sont en liaison (1,n) pour une ligne de A, plusieurs lignes de B

    Alors ce que je veux faire c'est de choisir les lignes de la table A qui n'ont QUE champ_B=12 par exemple.
    Quelqu'un aurait il une idée de la facon de mettre cela en place?

    Merci d'avance

  2. #2
    Membre expert

    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2004
    Messages
    2 862
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 862
    Points : 3 609
    Points
    3 609
    Par défaut
    Avec une clause exists par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    select *
    from tableA a
    where exists (select null 
                  from tableB b 
                  where b.idA=a.idA 
                    and champB=12);
    Un problème sans solution est un problème mal posé

    Merci de poser vos questions sur le forum, je ne réponds pas aux questions posées par MP.

  3. #3
    Membre actif
    Homme Profil pro
    Inscrit en
    Mars 2004
    Messages
    286
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 286
    Points : 279
    Points
    279
    Par défaut
    Je me demande si
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    select a.*
    from tableA a,tableB b
    where b.idA=a.idA 
                    and b.champB=12);
    ne serait pas un peu plus 'optimum'
    --
    ... Hello sweetie ...

  4. #4
    Membre émérite Avatar de nuke_y
    Profil pro
    Indépendant en analyse de données
    Inscrit en
    Mai 2004
    Messages
    2 076
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Indépendant en analyse de données

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 076
    Points : 2 370
    Points
    2 370
    Par défaut
    Certes si on considère qu'il n'existe qu'une seule ligne dans B pour laquelle champ_B=12, sinon ça duplique A et il faut mettre un distinct, et ça coûte plus cher.
    Il vaut mieux monopoliser son intelligence sur des bêtises que sa bêtise sur des choses intelligentes.

  5. #5
    Membre expert

    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2004
    Messages
    2 862
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 862
    Points : 3 609
    Points
    3 609
    Par défaut
    Citation Envoyé par Alain B.
    Je me demande si
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    select a.*
    from tableA a,tableB b
    where b.idA=a.idA 
                    and b.champB=12);
    ne serait pas un peu plus 'optimum'
    Pas forcément. Il faut pour cela étudier le plan d'exécution. Il n'y a pas de règles toute faite. Mais de manière générale, la clause exists est plus performante.
    Un problème sans solution est un problème mal posé

    Merci de poser vos questions sur le forum, je ne réponds pas aux questions posées par MP.

  6. #6
    Futur Membre du Club
    Inscrit en
    Avril 2004
    Messages
    14
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Avril 2004
    Messages : 14
    Points : 9
    Points
    9
    Par défaut
    Bonjour,
    Merci pour vos réponses, mais je pense que mon exemple avec mes tables A et B ne correspondait pas vraiment avec ce que je souhaitait reelement faire.
    Après quelques bon retournement du cervelet gauche j'ai réussi à troouver une soultion :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    SELECT * FROM ENTETE_OP WHERE NUM_OP IN ( 
                      SELECT DISTINCT NUM_OP FROM LIGNE_COLISEE 
                      WHERE NUM_OP IN (
                                 SELECT NUM_OP FROM LIGNE_COLISEE  
                                 WHERE (ID_PRODUIT=039353 OR ID_PRODUIT=636673                     
                                       OR ID_PRODUIT=636700 OR ID_PRODUIT=637464)
                                       AND ID_SOCIETE='PF'
                      MINUS
                                 SELECT  NUM_OP FROM LIGNE_COLISEE  
                                 WHERE ID_PRODUIT<>039353 AND ID_PRODUIT<>636673 
                                     AND ID_PRODUIT<>636700 AND ID_PRODUIT<>637464
                                     AND ID_SOCIETE='PF'
                      )
    )
    Bon voila je pense que vous vous en doutez, cette requete n'est pas du tout optimiser, j'obtiens un TABLE ACCESS FULL sur chaque requete utilisé pour l'operation MINUS.
    Pour info NUM_OP est la clé de la table ENTETE_OP, et est aussi un index dans la table LIGNE_COLISEE
    Si quelqu'un a une idée de la manière à proceder pour optimiser cette requete, qu'il le dise ou qu'il se taise à jamais !!!!

  7. #7
    McM
    McM est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    1 minus fait déjà un distinct
    1 IN (select ) : pas besoin de distinct

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    SELECT *
    FROM ENTETE_OP 
    WHERE NUM_OP IN (
    		SELECT NUM_OP 
    		FROM LIGNE_COLISEE a
    		WHERE (id_produit=039353 OR id_produit=636673 OR id_produit=636700 OR id_produit=637464)
    		AND id_societe='PF'
    		AND NOT EXISTS ( SELECT  1 
    				FROM LIGNE_COLISEE  
    				WHERE num_op  = a.num_op 
    				AND id_produit <> 039353 AND id_produit <> 636673 
    				AND id_produit <> 636700 AND id_produit <> 637464
    				AND id_societe='PF'
    				)
    		)
    et enfin avec des EXISTS et NOT EXISTS (tout dépend des index et de la taille de ta table principale)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    SELECT *
    FROM ENTETE_OP a 
    WHERE EXISTS (	SELECT 1
    		FROM LIGNE_COLISEE
    		WHERE (id_produit=039353 OR id_produit=636673 OR id_produit=636700 OR id_produit=637464)
    		AND id_societe='PF'
    		AND num_op = a.num_op
    		)
    AND NOT EXISTS ( SELECT  1 
    		FROM LIGNE_COLISEE  
    		WHERE num_op  = a.num_op 
    		AND id_produit <> 039353 AND id_produit <> 636673 
    		AND id_produit <> 636700 AND id_produit <> 637464
    		AND id_societe='PF'
    		)
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

  8. #8
    Futur Membre du Club
    Inscrit en
    Avril 2004
    Messages
    14
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Avril 2004
    Messages : 14
    Points : 9
    Points
    9
    Par défaut
    Merci beaucoup pour ta réponse,
    Ta solution améliore légèrement le temps d'éxécution, mais il y a encore un table access full!!!
    D'ou cela peut il venir?


    Ps: Dans ton code tu ecrit, LIGNE_COLISEE a, il ne faut pas mettre le a

  9. #9
    McM
    McM est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    Corrigé (un oubli lors du Copier-Coller)

    Tu as aussi cette option la, que tu peux décliner avec un IN
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    WHERE EXISTS (
    		SELECT 1
    		FROM LIGNE_COLISEE
    		WHERE id_societe='PF'
    		AND num_op = a.num_op
    		GROUP BY num_op
    		HAVING MAX(DECODE(id_produit, 039353, 1, 636673, 1, 636700, 1, 637464, 1, 2)) = 1
    		)
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

  10. #10
    Futur Membre du Club
    Inscrit en
    Avril 2004
    Messages
    14
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Avril 2004
    Messages : 14
    Points : 9
    Points
    9
    Par défaut
    , mais quelle requete !!!!!!
    En tout ca merci, elle marche très bien et je n'ai plus de table access full.
    Le petit revers de la medaille c'est qu'elle a un cout de 1002 contre 110 pour ton ancienne proposition.
    Alors ma derniere question sera la suivante :
    Sur une base de prod, ou il risque d'y avoir plus de 500 000 lignes dan sla table LIGNES_COLISEE, quelle sera la moins couteuse?

  11. #11
    Membre émérite Avatar de nuke_y
    Profil pro
    Indépendant en analyse de données
    Inscrit en
    Mai 2004
    Messages
    2 076
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Indépendant en analyse de données

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 076
    Points : 2 370
    Points
    2 370
    Par défaut
    Faut essayer
    Il vaut mieux monopoliser son intelligence sur des bêtises que sa bêtise sur des choses intelligentes.

  12. #12
    Futur Membre du Club
    Inscrit en
    Avril 2004
    Messages
    14
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Avril 2004
    Messages : 14
    Points : 9
    Points
    9
    Par défaut
    Citation Envoyé par nuke_y
    Faut essayer
    Ca m'étonnerait que cette réponse satisfasse le client!!!!

    Mais d'une manière générale, un table access full signifie que toutes les lignes sont parcourues, non? Donc plus il y a de lignes plus la durée d'execution est longue, non?

  13. #13
    McM
    McM est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    Non, faut voir non pas le coût, mais le nb de lecture Blocks.
    Après faut voir aussi les lectures multiblocks (lecture d'affilée, pas d'aller -retour) qui sont plus rapide.

    Bref, sous TOAD, tu as l'option de l'AutoTrace qui te donne les "consistent gets"
    La tu verras la meilleure requete, non pas en terme de durée, mais de qte de blocks lus.
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

  14. #14
    Membre éprouvé
    Inscrit en
    Avril 2006
    Messages
    1 024
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 1 024
    Points : 1 294
    Points
    1 294
    Par défaut
    Attention, il faut bien comprendre que le cout est une estimation en fonction des stats. Les traces vont donner le résultat en terme d'IO réellement effectués. Si dans la première requête, oracle a choisi de faire un access FULL, c'est qu'il a estimé que c'était moins couteux, ce en quoi il s'est peut etre trompé pour le cas particulier de cette requête.

    La 2ieme requête de mcm, lui force un autre plan d'exécution, c'est donc normal qu'à priori, il l'estime plus couteux que le premier (puisque c'est pas celui là qu'il avait pris quand il avait le choix), mais ça veux pas dire qu'il le soit... au contraire, s'il passe par les index, c'est rassurant à mon avis...

Discussions similaires

  1. Réponses: 1
    Dernier message: 25/01/2013, 15h41
  2. [XL-2007] Retrouver toutes les lignes qui ont une valeur identique dans la colonne A
    Par bartimeus35 dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 24/06/2012, 17h47
  3. Réponses: 6
    Dernier message: 10/11/2009, 11h58
  4. Réponses: 6
    Dernier message: 26/11/2008, 20h14
  5. Réponses: 5
    Dernier message: 19/01/2007, 22h53

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