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 :

[DB2] Requête imbriquée avec opérateur IN


Sujet :

Langage SQL

  1. #1
    Membre à l'essai
    Inscrit en
    Janvier 2005
    Messages
    38
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 38
    Points : 14
    Points
    14
    Par défaut [DB2] Requête imbriquée avec opérateur IN
    Bonjour,

    J'ai un problème : l'exécution d'une requête plutôt simple prend environ 150 secondes... la voici:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    UPDATE tmissdta.prr000f 
    SET CDLRPO = 0
    WHERE  NRPOL  in 
    (
        SELECT NRPOL
        from TMISSDTA.PRR130F 
        where nrprs = 01545454
    )
    Lorsque j'exécute la requête imbriquée seule, celà prends environ 270 ms...

    J'ai l'impression que le SGBD exécute la requête imbriquée pour chaque ligne de la table tmissdta.prr000f. Alors que c'est n'est pas
    une sous requête avec corrélation... :-S


    Le SGBD est DB2 sur un AS400 avec la V5R3.

  2. #2
    Inactif   Avatar de Médiat
    Inscrit en
    Décembre 2003
    Messages
    1 946
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 946
    Points : 2 227
    Points
    2 227
    Par défaut
    As-tu essayé avec un WHERE EXISTS (...) qui sera bien une requête avec corrélation, mais si elle est très perormante (usage des index), le temps devrait être raisonnable (mais cela dépend aussi (surtout ?) du nombre de lignes à mettre à jours).
    J'affirme péremptoirement que toute affirmation péremptoire est fausse
    5ième élément : barde-prince des figures de style, duc de la synecdoque
    Je ne réponds jamais aux questions techniques par MP

  3. #3
    Membre à l'essai
    Inscrit en
    Janvier 2005
    Messages
    38
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 38
    Points : 14
    Points
    14
    Par défaut
    Merci, mais ce n'est justement pas une requête avec corrélation!

  4. #4
    Membre à l'essai
    Inscrit en
    Janvier 2005
    Messages
    38
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 38
    Points : 14
    Points
    14
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    select a.NRPOL 
    from tmissdta.prr000f a
    WHERE EXISTS
    (
    SELECT b.NRPOL as N
    from TMISSDTA.PRR130F b
    where a.nrpol = b.nrpol
    and     b.nrprs = 1001020 
    )
    C'est beaucoup plus rapide... mais je pense que le SGBD fait mal son travail avec ma requête SQL avec IN...[/code]

  5. #5
    Membre à l'essai
    Inscrit en
    Janvier 2005
    Messages
    38
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 38
    Points : 14
    Points
    14
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    update tmissdta.prr000f a
    set cdlrpo = 2
    WHERE EXISTS
    (
    SELECT *
    from TMISSDTA.PRR130F b
    where a.nrpol = b.nrpol
    and     b.nrprs = 1001020 
    )
    Celà prend tout de même 60 secondes pour 2 lignes à mettre à jour ...

  6. #6
    Inactif   Avatar de Médiat
    Inscrit en
    Décembre 2003
    Messages
    1 946
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 946
    Points : 2 227
    Points
    2 227
    Par défaut
    Citation Envoyé par JFDelges
    PS : déso pour le multi-post, je me suis dit que ça devait être dans SQL et pas SGBD...
    Tout à fait d'accord, demande à un modérateur de supprimer ton message dans SQL et de déplacer tout ce fil là-bas.
    J'affirme péremptoirement que toute affirmation péremptoire est fausse
    5ième élément : barde-prince des figures de style, duc de la synecdoque
    Je ne réponds jamais aux questions techniques par MP

  7. #7
    Inactif   Avatar de Médiat
    Inscrit en
    Décembre 2003
    Messages
    1 946
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 946
    Points : 2 227
    Points
    2 227
    Par défaut
    Citation Envoyé par JFDelges
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    update tmissdta.prr000f a
    set cdlrpo = 2
    WHERE EXISTS
    (
    SELECT *
    from TMISSDTA.PRR130F b
    where a.nrpol = b.nrpol
    and     b.nrprs = 1001020 
    )
    Celà prend tout de même 60 secondes pour 2 lignes à mettre à jour ...
    Pure curiosité de ma part : que donne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    update tmissdta.prr000f a
    set cdlrpo = 2
    WHERE EXISTS
    (
    SELECT NULL
    from TMISSDTA.PRR130F b
    where a.nrpol = b.nrpol
    and     b.nrprs = 1001020 
    )
    J'affirme péremptoirement que toute affirmation péremptoire est fausse
    5ième élément : barde-prince des figures de style, duc de la synecdoque
    Je ne réponds jamais aux questions techniques par MP

  8. #8
    Membre à l'essai
    Inscrit en
    Janvier 2005
    Messages
    38
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 38
    Points : 14
    Points
    14
    Par défaut
    Pure curiosité de ma part : que donne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
     
    update tmissdta.prr000f a
    set cdlrpo = 2
    WHERE EXISTS
    (
    SELECT NULL
    from TMISSDTA.PRR130F b
    where a.nrpol = b.nrpol
    and     b.nrprs = 1001020
    )
    Eh bien... "la colonne NULL n'a pas été trouvée dans..."

    NB: C'est normal je trouve que le SQL pour DB2 n'est pas vraiment ce qu'il y a de plus standard...

  9. #9
    Inactif   Avatar de Médiat
    Inscrit en
    Décembre 2003
    Messages
    1 946
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 946
    Points : 2 227
    Points
    2 227
    Par défaut
    Citation Envoyé par JFDelges
    Eh bien... "la colonne NULL n'a pas été trouvée dans..."
    Oh qu'il est bête !
    J'affirme péremptoirement que toute affirmation péremptoire est fausse
    5ième élément : barde-prince des figures de style, duc de la synecdoque
    Je ne réponds jamais aux questions techniques par MP

  10. #10
    Membre à l'essai
    Inscrit en
    Janvier 2005
    Messages
    38
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 38
    Points : 14
    Points
    14
    Par défaut
    up ... Aucun expert en DB2 ici...?

  11. #11
    Membre chevronné

    Profil pro
    Inscrit en
    Avril 2005
    Messages
    1 673
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 673
    Points : 1 775
    Points
    1 775
    Par défaut
    Je ne suis absolument pas expert db2 mais voici quelques remarques :
    - as-tu vérifié la présence des index sur les colonnes concernées (ni trop ni trop peu) ?
    - quel est le temps de réponse de la requête suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT CDLRPO
    FROM TMISSDTA.PRR000F A
    WHERE EXISTS 
    ( 
        SELECT NULL 
        FROM TMISSDTA.PRR130F B
        WHERE A.NRPOL = B.NRPOL 
        AND     B.NRPRS = 1001020 
    )
    - pour information, la norme SQL interdit de mettre un alias sur la table à mettre dans une requête UPDATE
    Modérateur des forums Oracle et Langage SQL
    Forum SQL : je n'interviens PAS plus de 4 fois dans une discussion car si c'est nécessaire cela prouve généralement que vous n'avez pas respecté : les règles du forum

  12. #12
    Membre à l'essai
    Inscrit en
    Janvier 2005
    Messages
    38
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 38
    Points : 14
    Points
    14
    Par défaut
    Bon, je crois qu'on s'est un peu embrouillé avec ces exists...

    En résumé, le problème:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
        SELECT NRPOL
        FROM TMISSDTA.PRR130F  
        WHERE     NRPRS = 1001020
    Résultat (103 ms):
    2015030
    1003950

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    SELECT * 
    FROM tmissdta.prr000f 
    WHERE  NRPOL  in
    (
        2015030, 1003950
    )
    Résultat (282 ms):
    2 lignes complètes


    Le problème:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    SELECT * 
    FROM tmissdta.prr000f 
    WHERE  NRPOL  in
    (
         SELECT NRPOL
        FROM TMISSDTA.PRR130F  
        WHERE     NRPRS = 1001020
    )
    Résultat : 150000 ms !!


    PS : To Magnus : la requête que tu as mis prends 81 secondes à s'exécuter, mais puisqu'il y a corrélation c'est compréhensible sur 550000 lignes... et les indexs sont bien créés. Merci quand même :-)

  13. #13
    Membre habitué Avatar de souellet
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    155
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2003
    Messages : 155
    Points : 171
    Points
    171
    Par défaut
    Salut JFDelges,

    Disons que je suis pas pire en DB2, donc je vais essayer de t'aider.

    Pour ce qui est de ta requête de mise à jour, y'a pas vraiment d'autre façon de l'optimiser.

    Ce que je peux voir c'est un problème au niveau des index.

    Utilise l'éditeur de script Client Access pour voir ce que ta requête crée comme tables temporaires et index.

    Les index sont très utile pour accélérer les requêtes SELECT mais ralenti les requêtes D'UPDATE. Donc il faut bien analyser les besoin!

    Il pourrait aussi avoir un problème de mémoire ou de disque sur ta machine.

    Si t'as besoin d'aide, n'hésite pas!

  14. #14
    Membre à l'essai
    Inscrit en
    Janvier 2005
    Messages
    38
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 38
    Points : 14
    Points
    14
    Par défaut
    Salut souellet, merci pour ta réponse!

    En fait à la base je voulais créer un trigger pour mettre à jour des données automatiquement... j'ai opté pour une autre solution en attendant.


    Mais j'aimerais toujours comprendre pourquoi la requête de sélection pose problème...

    Tu m'a parlé de "l'éditeur de script Client Access"
    Est-ce que tu penses à l'outil dans
    iSeries Navigator -> Base de données -> Exécution de scripts SQL-> Exécution et explications (Visual Explain) ?

    Si oui, cet outil ne m'aide pas beaucoup: je peux juste voir que l'analyseur fait une "jointure hachée" et je ne vois pas vraiment si la sous-requête est exécutée plusieurs fois ou non.

    Mais merci quand même, ami du Québec !

  15. #15
    Membre habitué Avatar de souellet
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    155
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2003
    Messages : 155
    Points : 171
    Points
    171
    Par défaut
    C'est en effet Visual Explain.
    Faut regarder dans les attributs l'index utilisé et si il y a création d'index recommandée.

    Visual Explain ne te dis pas comment optimiser la requête mais il te dit ce qu'il a fait.

    Peut-être qu'on est rendu un peu trop DB2 pour continuer la discussion sur le site?

    Si tu veux, tu peux me contacter par courriel et me donner les renseignement sur ta version Client Access et quelques print screen de Visual Explain.

    J'ai aussi la possibilité de créer les tables et faire les tests.

    Ça va me faire plaisir.

  16. #16
    Membre habitué Avatar de souellet
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    155
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2003
    Messages : 155
    Points : 171
    Points
    171
    Par défaut
    Citation Envoyé par JFDelges
    ... et je ne vois pas vraiment si la sous-requête est exécutée plusieurs fois ou non.
    Pour cette question, oui la sous requête est exécuté pour chaque record.
    Si c'est possible, tu dois encore diminuer ta plage de records en soyant plus spécifique dans ta clause where sans faire d'autre sous-requête.

  17. #17
    Membre habitué Avatar de souellet
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    155
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2003
    Messages : 155
    Points : 171
    Points
    171
    Par défaut
    Si tu trouves une solution, tu nous la fera partager!

    A+

  18. #18
    Membre à l'essai
    Inscrit en
    Janvier 2005
    Messages
    38
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 38
    Points : 14
    Points
    14
    Par défaut
    Pour l'instant rien trouvé qui m'avance plus ...

    Je pense que DB2 traite la requête non-corrélée comme s'il s'agissait d'une requête corrélée.

    -> Exécution de la sous requête pour chaque ligne de la requête principale alors que le résultat de la sous requête est indépendant de la requête principale.

  19. #19
    Membre à l'essai
    Inscrit en
    Janvier 2005
    Messages
    38
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 38
    Points : 14
    Points
    14
    Par défaut
    J'ai posé la question sur un forum plus approprié...

    http://www.tek-tips.com/viewthread.cfm?qid=1156212

    Mais mis à part créer une procédure stockée, malheureusement tjrs pas de solution...

  20. #20
    Membre habitué Avatar de souellet
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    155
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2003
    Messages : 155
    Points : 171
    Points
    171
    Par défaut
    J'ai déjà essayé la StoredProc et ça rien donné de plus.

Discussions similaires

  1. Requête imbriquée avec deux "rangements par ordre de"
    Par reivinternet dans le forum PostgreSQL
    Réponses: 17
    Dernier message: 09/12/2010, 10h34
  2. Requête imbriquée avec group by
    Par pobrouwers dans le forum Langage SQL
    Réponses: 6
    Dernier message: 11/06/2009, 00h56
  3. Réponses: 3
    Dernier message: 04/07/2008, 17h03
  4. Construction d'une requête "imbriquée" avec Oracle
    Par kyra78 dans le forum Langage SQL
    Réponses: 0
    Dernier message: 05/02/2008, 14h29
  5. [MySQL] Erreur SQL 1064 : Requête imbriquée avec jointure !
    Par patchankito dans le forum Langage SQL
    Réponses: 5
    Dernier message: 31/01/2006, 10h37

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