Bonjour,
On me demande d'optimiser la requête suivante:
Voici ce que donne l'autotrace:
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 SELECT P.IDINPS, NVL(TO_CHAR(P.DARSEF, 'DD-MON-YY'), 'XXXXXXXXX') 2 FROM PSTEGF P, CTINGF C, (SELECT MAX(PS.IDINPS) as IDINPS 3 FROM PSTEGF PS, CTINGF CT 4 WHERE 5 PS.IDEXP1 = 'A115332' 6 AND PS.TYPSTE = 'ARP' 7 AND 8 PS.NUCTIN = CT.NUCTIN 9 AND CT.CDOFIN = 'ARPEGE_OPT' 10 AND PS.DATEAC IS NULL 11 ) ID_MAX 12 WHERE 13 P.IDEXP1 = 'A115332' 14 AND P.TYPSTE = 'ARP' 15 AND 16 P.NUCTIN = C.NUCTIN 17 AND C.CDOFIN = 'ARPEGE_OPT' 18 AND P.DATEAC IS NULL 19 AND C.DATEAC IS NULL 20 AND ID_MAX.IDINPS = P.IDINPS;
Voyez-vous quelque chose de choquant dans cette requête ?
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 Ecoulé : 00 :00 :00.07 Plan d'exécution ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE (Cost=53 Card=1 Bytes=68) 1 0 TABLE ACCESS (BY INDEX ROWID) OF 'CTINGF' (TABLE) (Cost=6 Card=1 Bytes=19) 2 1 NESTED LOOPS (Cost=53 Card=1 Bytes=68) 3 2 NESTED LOOPS (Cost=47 Card=1 Bytes=49) 4 3 VIEW (Cost=27 Card=1 Bytes=7) 5 4 SORT (AGGREGATE) 6 5 TABLE ACCESS (BY INDEX ROWID) OF 'CTINGF' (TABLE) (Cost=6 Card=1 Byt es=13) 7 6 NESTED LOOPS (Cost=27 Card=1 Bytes=52) 8 7 TABLE ACCESS (BY INDEX ROWID) OF 'PSTEGF' (TABLE) (Cost=21 Card= 1 Bytes=39) 9 8 INDEX (RANGE SCAN) OF 'PSTEGF_FK7' (INDEX) (Cost=3 Card=18) 10 7 INDEX (RANGE SCAN) OF 'CTINGF_FK5' (INDEX) (Cost=2 Card=3) 11 3 TABLE ACCESS (BY INDEX ROWID) OF 'PSTEGF' (TABLE) (Cost=20 Card=1 Bytes= 42) 12 11 INDEX (RANGE SCAN) OF 'PSTEGF_FK6' (INDEX) (Cost=2 Card=17) 13 2 INDEX (RANGE SCAN) OF 'CTINGF_FK5' (INDEX) (Cost=2 Card=3) Statistiques ---------------------------------------------------------- 1 recursive calls 0 db block gets 88 consistent gets 0 physical reads 0 redo size 299 bytes sent via SQL*Net to client 275 bytes received via SQL*Net from client 4 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1 rows processed
Il s'agit d'une requête qui est exécutée dans une boucle plusieurs centaine de milliers de fois.
en remplacant la vue en ligne suivante:
par une sous requête dans la clause where :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 (SELECT MAX(PS.IDINPS) as IDINPS FROM PSTEGF PS, CTINGF CT WHERE PS.IDEXP1 = 'A115332' AND PS.TYPSTE = 'ARP' AND PS.NUCTIN = CT.NUCTIN AND CT.CDOFIN = 'ARPEGE_OPT' AND PS.DATEAC IS NULL ) ID_MAX
j'obtiens le plan d'exécution suivant:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 AND P.IDINPS = (select max(PS.IDINPS) FROM PSTEGF PS, CTINGF CT WHERE PS.IDEXP1 = 'A115332' AND PS.TYPSTE = 'ARP' AND PS.NUCTIN = CT.NUCTIN AND CT.CDOFIN = 'ARPEGE_OPT' AND PS.DATEAC IS NULL )
A priori c'est meilleur car je passe de 7 secondes à une seconde mais pourquoi?? J'avais lu qu'il fallait toujours préférer les vues en ligne au sous requête
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 Ecoulé : 00 :00 :00.01 Plan d'exécution ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE (Cost=39 Card=1 Bytes=61) 1 0 TABLE ACCESS (BY INDEX ROWID) OF 'CTINGF' (TABLE) (Cost=6 Card=1 Bytes=19) 2 1 NESTED LOOPS (Cost=12 Card=1 Bytes=61) 3 2 TABLE ACCESS (BY INDEX ROWID) OF 'PSTEGF' (TABLE) (Cost=6 Card=1 Bytes=42) 4 3 BITMAP CONVERSION (TO ROWIDS) 5 4 BITMAP AND 6 5 BITMAP CONVERSION (FROM ROWIDS) 7 6 INDEX (RANGE SCAN) OF 'PSTEGF_FK6' (INDEX) (Cost=3 Card=17) 8 7 SORT (AGGREGATE) 9 8 TABLE ACCESS (BY INDEX ROWID) OF 'CTINGF' (TABLE) (Cost=6 Card =1 Bytes=13) 10 9 NESTED LOOPS (Cost=27 Card=1 Bytes=52) 11 10 TABLE ACCESS (BY INDEX ROWID) OF 'PSTEGF' (TABLE) (Cost=21 Card=1 Bytes=39) 12 11 INDEX (RANGE SCAN) OF 'PSTEGF_FK7' (INDEX) (Cost=3 Card= 18) 13 10 INDEX (RANGE SCAN) OF 'CTINGF_FK5' (INDEX) (Cost=2 Card=3) 14 5 BITMAP CONVERSION (FROM ROWIDS) 15 14 INDEX (RANGE SCAN) OF 'PSTEGF_FK7' (INDEX) (Cost=3 Card=17) 16 2 INDEX (RANGE SCAN) OF 'CTINGF_FK5' (INDEX) (Cost=2 Card=3) Statistiques ---------------------------------------------------------- 0 recursive calls 0 db block gets 91 consistent gets 0 physical reads 0 redo size 299 bytes sent via SQL*Net to client 275 bytes received via SQL*Net from client 4 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1 rows processed
Partager