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 :

Réécriture sous-requête : équivalent ?


Sujet :

Langage SQL

  1. #1
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 154
    Points : 7 403
    Points
    7 403
    Billets dans le blog
    1
    Par défaut Réécriture sous-requête : équivalent ?
    Bonjour,

    Dans le cadre de mes recherches pour optimiser une vue complexe, je tente de faire une simplification mais j'aimerais maîtriser les effets de bord.

    J'ai une requête SQL de ce type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    select * from ma_vue where dat1 between <une date> and <une autre date>;
    Et la vue est de ce type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    create view ma_vue as
    select cde.numeve, (select max(liv.datliv) from eve liv where liv.cde_id = cde.id) dat1
    from eve cde;
    Actuellement, c'est donc très lent, puisque pour retrouver les CDE dont j'ai besoin, je doit me taper l'ensemble des CDE, rechercher toutes les LIV à chaque fois, puis ne retenir que les CDE dont le max des LIV est bien compris dans mes dates...

    Je tente donc de réécrire la vue comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    create view ma_vue as
    select cde.numeve, max(liv.datliv) dat1
    from eve cde
    inner join eve liv on liv.cde_id = cde.id;
    1/ Est-ce que je peux espérer un gain significatif de performances ?
    2/ Est-ce qu'il y a des pièges à éviter ? C'est à dire que les deux syntaxes sont-elles absolument équivalentes (mise à part la possibilité de ne pas avoir de LIV pour une CDE, dans mon cas précis, je ne veux de toute façon que celles qui ont au moins une LIV)

    En effet, les requêtes mettent un temps pas possible à tourner, et je doute pouvoir faire une comparaison des résultats des deux requêtes...
    On ne jouit bien que de ce qu’on partage.

  2. #2
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    Bonjour,

    Ne manquerai-t-il pas un group by ?


    Sinon :
    1/ Oui forcément, vous passez d'une requête scalaire à une requête "normale"
    2/ pour l'équivalence il faudrai passer par un left outer join

  3. #3
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 154
    Points : 7 403
    Points
    7 403
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par punkoff Voir le message
    Bonjour,

    Ne manquerai-t-il pas un group by ?


    Sinon :
    1/ Oui forcément, vous passez d'une requête scalaire à une requête "normale"
    2/ pour l'équivalence il faudrai passer par un left outer join
    En effet, j'ai oublié le group by dans mon post. Mais je l'ai bien mis dans mon code

    En effet, pour une équivalence de la vue, il faudrait un group by.
    Mais la vue ne sera utilisée que par la requête ci-dessus. Le between sur la date va donc filtrer les NULL, et c'est pourquoi j'ai mis un INNER JOIN (ce que j'ai indiqué dans mon poste).

    Pas d'autre piège en vue ?


    La vue au final, c'est ça (j'avais dit que c'était plus compliqué) :
    Initiale :
    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
     
    CREATE OR REPLACE FORCE VIEW "SOC1"."WV_QIFM30" ("CODSOC", "LIB1", "LIB2", "LIB3", "LIB4", "LIB5", "LIB6", "LIB7", "LIB8", "LIB9", "LIB10", "LIB11", "LIB12", "LIB13", "LIB14", "LIB15", "LIB16", "LIB17", "LIB18", "LIB19", "LIB20", "DAT1", "DAT2", "DAT3", "DAT4", "DAT5", "NUM01", "NUM02", "NUM03", "NUM04", "NUM05", "NUM06", "NUM07", "NUM08", "NUM09", "NUM10", "VAL01", "VAL02", "VAL03", "VAL04", "VAL05", "VAL06", "VAL07", "VAL08", "VAL09", "VAL10", "VAL11", "VAL12", "VAL13", "VAL14", "VAL15", "VAL16", "VAL17", "VAL18", "VAL19", "VAL20")
    AS
      SELECT cde.codsoc,
        cde.achvte,
        cde.typeve,
        DECODE( UPPER(SUBSTR(tie.codzn16,1,1)),'P',upper(tie.codzn16), '000'
        ||SUBSTR(tie.sigtie,2,5)),
        cde.codeta,
        tie.codett,
        SUBSTR(DECODE(NVL(trim(prc.codzn2), ' '), ' ', pro.codzn15, prc.codzn2),2,8),
        /*liv.datliv*/
        (SELECT MAX(liv.datliv)
        FROM eve liv
        WHERE liv.codsoc = cde.codsoc
        AND liv.achvto   = cde.achvte
        AND liv.typevo   = cde.typeve
        AND liv.numevo   = cde.numeve
        ),
        cdp.codpro,
        ' ',
        pro.codzn10,
        cde.codctg,
        'XXX',
        ' ',
        ' ',
        ' ',
        ' ',
        ' ',
        ' ',
        ' ',
        ' ',
        /*liv.datliv*/
        (
        SELECT MAX(liv.datliv)
        FROM eve liv
        WHERE liv.codsoc = cde.codsoc
        AND liv.achvto   = cde.achvte
        AND liv.typevo   = cde.typeve
        AND liv.numevo   = cde.numeve
        ) ,
        ' ',
        ' ',
        ' ',
        ' ',
        cde.numeve,
        NVL(to_number(trim(evt.codzn5)), cdp.qtecde),
        0,0,0,
        0,0,0,0,0,
        pru.coefuv,
        0,0,0,0,
        0,0,0,0,0,
        0,0,0,0,0,
        0,0,0,0,0
      FROM eve cde
      INNER JOIN tie
      ON tie.codsoc  = cde.codsoc
      AND tie.typtie = 'CLI'
      AND tie.sigtie = cde.sigtie
      INNER JOIN evp cdp
      ON cdp.codsoc  = cde.codsoc
      AND cdp.achvte = cde.achvte
      AND cdp.typeve = cde.typeve
      AND cdp.numeve = cde.numeve
      INNER JOIN pro
      ON pro.codsoc  = cdp.codsoc
      AND pro.codpro = cdp.codpro
      INNER JOIN prl
      ON prl.codsoc  = pro.codsoc
      AND prl.codpro = pro.codpro
      AND prl.typtie = ' '
      AND prl.sigtie = ' '
      AND prl.codva1 = '00'
      AND prl.codva2 = SUBSTR(pro.codpro,8,2)
      AND prl.cntcod = ' '
      INNER JOIN pru
      ON pru.codsoc  = prl.codsoc
      AND pru.codpro = prl.codpro
      AND pru.coduni = prl.coduni1
      INNER JOIN evt
      ON evt.codsoc  = cdp.codsoc
      AND evt.achvte = cdp.achvte
      AND evt.typeve = cdp.typeve
      AND evt.numeve = cdp.numeve
      AND evt.numpos = cdp.numpos
      AND evt.numlig = 0
      AND evt.numspo = 0
      AND evt.numblo = 0
      LEFT OUTER JOIN prc
      ON prc.codsoc         = cde.codsoc
      AND prc.typtie        = 'CLI'
      AND prc.sigfou        = tie.sigtie
      AND prc.codpro        = pro.codpro
      WHERE cde.codctg NOT IN ('DE','GR','EC');
    Modifiée :
    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
     
    CREATE OR REPLACE FORCE VIEW WV_QIFM30_bis (CODSOC, LIB1, LIB2, LIB3, LIB4, LIB5, LIB6, LIB7, LIB8, LIB9, LIB10, LIB11, LIB12, LIB13, LIB14, LIB15, LIB16, LIB17, LIB18, LIB19, LIB20, DAT1, DAT2, DAT3, DAT4, DAT5, NUM01, NUM02, NUM03, NUM04, NUM05, NUM06, NUM07, NUM08, NUM09, NUM10, VAL01, VAL02, VAL03, VAL04, VAL05, VAL06, VAL07, VAL08, VAL09, VAL10, VAL11, VAL12, VAL13, VAL14, VAL15, VAL16, VAL17, VAL18, VAL19, VAL20)
    AS
    SELECT cde.codsoc,
        cde.achvte,
        cde.typeve,
        DECODE( UPPER(SUBSTR(tie.codzn16,1,1)),'P',upper(tie.codzn16), '000'
        ||SUBSTR(tie.sigtie,2,5)),
        cde.codeta,
        tie.codett,
        SUBSTR(DECODE(NVL(trim(prc.codzn2), ' '), ' ', pro.codzn15, prc.codzn2),2,8),
        max(liv.datliv),
        cdp.codpro,
        ' ',
        pro.codzn10,
        cde.codctg,
        'XXX',
        ' ',
        ' ',
        ' ',
        ' ',
        ' ',
        ' ',
        ' ',
        ' ',
        max(liv.datliv),
        ' ',
        ' ',
        ' ',
        ' ',
        cde.numeve,
        NVL(to_number(trim(evt.codzn5)), cdp.qtecde),
        0,0,0,
        0,0,0,0,0,
        pru.coefuv,
        0,0,0,0,
        0,0,0,0,0,
        0,0,0,0,0,
        0,0,0,0,0
      FROM eve cde
      inner join eve liv on liv.codsoc = cde.codsoc and liv.achvto = cde.achvte and liv.typevo = cde.typeve and liv.numevo = cde.numeve and liv.achvte = 'V' and liv.typeve = 'LIV' 
      INNER JOIN tie
      ON tie.codsoc  = cde.codsoc
      AND tie.typtie = 'CLI'
      AND tie.sigtie = cde.sigtie
      INNER JOIN evp cdp
      ON cdp.codsoc  = cde.codsoc
      AND cdp.achvte = cde.achvte
      AND cdp.typeve = cde.typeve
      AND cdp.numeve = cde.numeve
      INNER JOIN pro
      ON pro.codsoc  = cdp.codsoc
      AND pro.codpro = cdp.codpro
      INNER JOIN prl
      ON prl.codsoc  = pro.codsoc
      AND prl.codpro = pro.codpro
      AND prl.typtie = ' '
      AND prl.sigtie = ' '
      AND prl.codva1 = '00'
      AND prl.codva2 = SUBSTR(pro.codpro,8,2)
      AND prl.cntcod = ' '
      INNER JOIN pru
      ON pru.codsoc  = prl.codsoc
      AND pru.codpro = prl.codpro
      AND pru.coduni = prl.coduni1
      INNER JOIN evt
      ON evt.codsoc  = cdp.codsoc
      AND evt.achvte = cdp.achvte
      AND evt.typeve = cdp.typeve
      AND evt.numeve = cdp.numeve
      AND evt.numpos = cdp.numpos
      AND evt.numlig = 0
      AND evt.numspo = 0
      AND evt.numblo = 0
      LEFT OUTER JOIN prc
      ON prc.codsoc         = cde.codsoc
      AND prc.typtie        = 'CLI'
      AND prc.sigfou        = tie.sigtie
      AND prc.codpro        = pro.codpro
      WHERE cde.codctg NOT IN ('DE','GR','EC')
      group by cde.codsoc, cde.achvte, cde.typeve, DECODE( UPPER(SUBSTR(tie.codzn16,1,1)),'P',upper(tie.codzn16), '000' ||SUBSTR(tie.sigtie,2,5)), cde.codeta, tie.codett, SUBSTR(DECODE(NVL(trim(prc.codzn2), ' '), ' ', pro.codzn15, prc.codzn2),2,8), cdp.codpro, pro.codzn10, cde.codctg, cde.numeve, NVL(to_number(trim(evt.codzn5)), cdp.qtecde), pru.coefuv;
    On ne jouit bien que de ce qu’on partage.

Discussions similaires

  1. [MFC] [API mySQL] Sous requêtes
    Par Guybrush113 dans le forum MFC
    Réponses: 5
    Dernier message: 29/04/2004, 16h14
  2. Problème DBExpress et sous requêtes ???
    Par Trulane dans le forum Bases de données
    Réponses: 5
    Dernier message: 26/03/2004, 14h40
  3. Requêtes et sous requêtes
    Par lau2nyce dans le forum Langage SQL
    Réponses: 3
    Dernier message: 23/03/2004, 15h14
  4. suppression avec sous requête conditionnelle
    Par melmel dans le forum Requêtes
    Réponses: 8
    Dernier message: 18/03/2004, 23h20
  5. Réponses: 3
    Dernier message: 18/05/2003, 00h16

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