Salut
Je viens à vous pour vous faire part d'un comportement étrange de l'optimizer d'oracle, je souhaite comprendre pourquoi ses décisions changent pour 2 requêtes (explain plan) alors que visiblement il n'y a aucun changement logique entre les 2.
Voici les requêtes, je vous les mets en entier car je ne sais pas trop si les simplifier serait une bonne chose pour le fond du problème.
La seule différence entre les 2 est mise en caractères gras :
REQUETE 1:
REQUETE 2:
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 SELECT ampaclav clav, CASE WHEN ampaesta||AMPAMARC||AMPATIPO||SUBSTR(AMPACTAC,1,4) = '0138889' THEN ' ' ELSE SUBSTR(TO_CHAR(ampactac),1,4) || '/' || SUBSTR(TO_CHAR(ampactac),5,4) || SUBSTR(TO_CHAR(ampactac),10) END NumCuenta, a.RELACLA2 NumTarjeta, SUBSTR(a.RELACLA2,3,4) || ' ' || SUBSTR(a.RELACLA2,7,4) || ' XXXX ' || SUBSTR(a.RELACLA2,15,4) Tarjeta, DECODE(ampaesta||AMPAMARC||AMPATIPO||SUBSTR(AMPACTAC,1,4),'0138889','CORPORATE',SUBSTR(pdudata,41,LENGTH(pdudata)-42)) Tipo, CASE WHEN SUBSTR(a.RELACLA2,3,6) = '459992' THEN 'A' WHEN SUBSTR(a.RELACLA2,3,6) = '459993' THEN 'A' WHEN SUBSTR(a.RELACLA2,3,6) = '459994' THEN 'D' WHEN SUBSTR(a.RELACLA2,3,6) = '603977' THEN 'C' END Modo FROM golf.PDU, golf.rela a, golf.ampa, golf.pers WHERE PDUTBLA = 'MPBINES' AND SUBSTR(a.RELACLA2,3,6) = pduclav AND ampaclav = SUBSTR(a.RELACLA2,3) AND persnume = RELACLA1 AND ( a.RELAMAE1 = 'PERS' AND a.RELAMAE2 = 'AMPA' AND ( a.RELACLA1 = LPAD(ParCliente,18, '0') AND perssexo < 5) OR ( RELACLA1 = persnume AND ampatita = 'B' AND SUBSTR(ampaclav,1,13) IN ( SELECT SUBSTR(ampaclav,1,13) FROM golf.ampa WHERE ampaclav IN ( SELECT SUBSTR(RELACLA2,3) FROM golf.rela, golf.pers WHERE RELACLA1 = LPAD(ParCliente,18,'0') AND persnume = RELACLA1 AND RELAMAE1 = 'PERS' AND RELAMAE2 = 'AMPA' AND TO_NUMBER(RELACLA1) = persnume AND perssexo > 5 AND ampatita = 'P' ) ) ) ) ORDER BY ampactac
Le changement, comme vous pouvez le constater, est très simple. On a un séquent de type
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 SELECT ampaclav clav, CASE WHEN ampaesta||AMPAMARC||AMPATIPO||SUBSTR(AMPACTAC,1,4) = '0138889' THEN ' ' ELSE SUBSTR(TO_CHAR(ampactac),1,4) || '/' || SUBSTR(TO_CHAR(ampactac),5,4) || SUBSTR(TO_CHAR(ampactac),10) END NumCuenta, a.RELACLA2 NumTarjeta, SUBSTR(a.RELACLA2,3,4) || ' ' || SUBSTR(a.RELACLA2,7,4) || ' XXXX ' || SUBSTR(a.RELACLA2,15,4) Tarjeta, DECODE(ampaesta||AMPAMARC||AMPATIPO||SUBSTR(AMPACTAC,1,4),'0138889','CORPORATE',SUBSTR(pdudata,41,LENGTH(pdudata)-42)) Tipo, CASE WHEN SUBSTR(a.RELACLA2,3,6) = '459992' THEN 'A' WHEN SUBSTR(a.RELACLA2,3,6) = '459993' THEN 'A' WHEN SUBSTR(a.RELACLA2,3,6) = '459994' THEN 'D' WHEN SUBSTR(a.RELACLA2,3,6) = '603977' THEN 'C' END Modo FROM golf.PDU, golf.rela a, golf.ampa, golf.pers WHERE PDUTBLA = 'MPBINES' AND SUBSTR(a.RELACLA2,3,6) = pduclav AND ampaclav = SUBSTR(a.RELACLA2,3) AND persnume = RELACLA1 AND a.RELAMAE1 = 'PERS' AND a.RELAMAE2 = 'AMPA' AND ( ( a.RELACLA1 = LPAD(ParCliente,18, '0') AND perssexo < 5) OR ( RELACLA1 = persnume AND ampatita = 'B' AND SUBSTR(ampaclav,1,13) IN ( SELECT SUBSTR(ampaclav,1,13) FROM golf.ampa WHERE ampaclav IN ( SELECT SUBSTR(RELACLA2,3) FROM golf.rela, golf.pers WHERE RELACLA1 = LPAD(ParCliente,18,'0') AND persnume = RELACLA1 AND RELAMAE1 = 'PERS' AND RELAMAE2 = 'AMPA' AND TO_NUMBER(RELACLA1) = persnume AND perssexo > 5 AND ampatita = 'P' ) ) ) ) ORDER BY ampactac
(A and (B AND (C OR D)))
qu'on transforme en
(A and B AND (C OR D))
Cependant, les explains plan sont différent, dans un cas il utilise un FULL FAST INDEX SCAN d'un index non unique, dans l'autre il utilise un RANGE INDEX SCAN d'un index non unique non plus. Ce sont les 2 seules différences entre les explains plan.
Je ne comprends pas, je n'ai fait que sortir d'une parenthèse une expression basique ...
Partager