Précédent   Forum des professionnels en informatique > Bases de données > Langage SQL
Langage SQL Forum d'entraide sur le langage SQL et sur les questions liées à la conception de schéma (DDL). Cours SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 09/01/2012, 15h09   #1
Membre Expert
 
Homme Sylvain Devidal
Chef de projets Générix
Inscription : février 2010
Messages : 1 062
Détails du profil
Informations personnelles :
Nom : Homme Sylvain Devidal
Âge : 33
Localisation : France, Rhône (Rhône Alpes)

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

Informations forums :
Inscription : février 2010
Messages : 1 062
Points : 1 515
Points : 1 515
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 :
1
2
 
SELECT * FROM ma_vue WHERE dat1 BETWEEN <une date> AND <une autre date>;
Et la vue est de ce type :
Code :
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 :
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...
StringBuilder est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/01/2012, 15h19   #2
Expert Confirmé
 
Homme
Inscription : mai 2002
Messages : 1 657
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : mai 2002
Messages : 1 657
Points : 2 660
Points : 2 660
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
punkoff est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/01/2012, 15h27   #3
Membre Expert
 
Homme Sylvain Devidal
Chef de projets Générix
Inscription : février 2010
Messages : 1 062
Détails du profil
Informations personnelles :
Nom : Homme Sylvain Devidal
Âge : 33
Localisation : France, Rhône (Rhône Alpes)

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

Informations forums :
Inscription : février 2010
Messages : 1 062
Points : 1 515
Points : 1 515
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 :
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 :
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;
StringBuilder est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 09h13.


 
 
 
 
Partenaires

Hébergement Web