Bonjour tout le monde,

Je continue mon voyage au sein de l'optimiseur Oracle; fascinant mais ardu par moment.

Dernièrement je me suis posé une question toute bête : comment être sur que le CBO utilise bien mes hints?
J'ai lu que si je fais une erreur de syntaxe en utilisant un hint, Oracle n'affiche aucun message d'erreur. OK, mais si la syntaxe est correcte et qu'il l'utilise bien, comment le valider? Facile vous me direz : il suffit de voir le plan d'exécution; on devrait voir les lignes liés au hint PARRALEL, celles sur l'index dont je veux forcer l'utilisation...

OK, mais si je me trompe sur la syntaxe du hint (forcer l'utilisation d'un index par exemple) et que le CBO utilise quand même cet index, je vais être trompé sur la syntaxe du hint.

J'ai donc cherché sur le Net et c'est pas terrible; à croire que je suis le seul à me poser ce genre de question

Néanmoins j'ai trouvé deux requêtes : select * from table(dbms_xplan.display_cursor(null, null, 'advanced')); ou select * from table(dbms_xplan.display_cursor(null, null, 'outline')); des plus intéressantes.


Je fais une recherche dans ma table bic_code.
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
select  /*+   parallel(b,10) */  * from bic_code b where rownum < 100;  
select * from table(dbms_xplan.display_cursor(null, null, 'advanced'));


PLAN_TABLE_OUTPUT                                                               
--------------------------------------------------------------------------------
SQL_ID  2ut1kawn1yg75, child number 0                                           
-------------------------------------                                           
select  /*+   parallel(b,10) */  * from bic_code b where rownum < 100           
                                                                                
Plan hash value: 2632626061                                                     
                                                                                
------------------------------------------------------------------------------- 
| Id  | Operation          | Name     | Rows  | Bytes | Cost (%CPU)| Time     | 
------------------------------------------------------------------------------- 
|   0 | SELECT STATEMENT   |          |       |       |     4 (100)|          | 
|*  1 |  COUNT STOPKEY     |          |       |       |            |          | 
|   2 |   TABLE ACCESS FULL| BIC_CODE |    99 |  4554 |     4   (0)| 00:00:01 | 
------------------------------------------------------------------------------- 
                                                                                
Query Block Name / Object Alias (identified by operation id):                   
-------------------------------------------------------------                   
                                                                                
   1 - SEL$1                                                                    
   2 - SEL$1 / B@SEL$1                                                          
                                                                                
Outline Data                                                                    

PLAN_TABLE_OUTPUT                                                               
--------------------------------------------------------------------------------                  
  /*+                                                                           
      BEGIN_OUTLINE_DATA                                                        
      IGNORE_OPTIM_EMBEDDED_HINTS                                               
      OPTIMIZER_FEATURES_ENABLE('11.2.0.3')                                     
      DB_VERSION('11.2.0.3')                                                    
      ALL_ROWS                                                                  
      OUTLINE_LEAF(@"SEL$1")                                                    
      FULL(@"SEL$1" "B"@"SEL$1")                                                
      END_OUTLINE_DATA                                                          
  */                                                                            
                                                                                
Predicate Information (identified by operation id):                             
---------------------------------------------------                             
                                                                                
   1 - filter(ROWNUM<100)                                                       
                                                                                
Column Projection Information (identified by operation id):                     
-----------------------------------------------------------                     
PLAN_TABLE_OUTPUT                                                               
--------------------------------------------------------------------------------
   1 - "B"."BIC_BANK_CODE"[VARCHAR2,8],                                         
       "B"."BIC_BRANCH_CODE"[VARCHAR2,3], "B"."BIC_NAME"[VARCHAR2,35],          
       "B"."IC_BIC_CAC_TO_CAC_AUTH"[VARCHAR2,3],                                
       "B"."IC_BIC_TYPE"[VARCHAR2,3], "B"."BIC_END_DATE"[DATE,7]                
   2 - "B"."BIC_BANK_CODE"[VARCHAR2,8],                                         
       "B"."BIC_BRANCH_CODE"[VARCHAR2,3], "B"."BIC_NAME"[VARCHAR2,35],          
       "B"."IC_BIC_CAC_TO_CAC_AUTH"[VARCHAR2,3],                                
       "B"."IC_BIC_TYPE"[VARCHAR2,3], "B"."BIC_END_DATE"[DATE,7]                
                                                                                
51 rows selected.

Je ne vois aucune trace dans le plan d'exécution de parallélisme
Et, f**k, je vois une ligne "IGNORE_OPTIM_EMBEDDED_HINTS" qui ne me plait ABSOLUMENT PAS car il y a IGNORE et HINT.

Sur le net (mais pas sur le site de Oracle malheureusement) je lis "IGNORE_OPTIM_EMBEDDED_HINTS : this special hint instructs the CBO to ignore most of all the other supplied hints (there are some exceptions to this) except the ones that are flanked by BEGIN_OUTLINE_DATA and END_OUTLINE_DATA (= outline hints)".

Euh, est-ce que ça veut dire que ce paramètre empêche l'utilisation des hints sur ma base de données?
Pourquoi sur tous les sites parlant de hints il n'est jamais mentionné?

La commande "show parameter IGNORE_OPTIM_EMBEDDED_HINTS" ne renvoit rien donc où est géré ce paramètre?



Autre test car ça m'énerve bien cette histoire : j'utilise le vieux hint RULE et là je vois qu'il est utilisé car la ligne RBO remplace la ligne ALL_ROWS (est-ce une des exceptions sus-mentionnée?).
Autre preuve : une note parle du RBO "Note rule based optimizer used (consider using cbo)".

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
select  /*+   RULE */  * from bic_code b where rownum < 100;  
select * from table(dbms_xplan.display_cursor(null, null, 'advanced'));

PLAN_TABLE_OUTPUT                                                               
--------------------------------------------------------------------------------
SQL_ID  392rr3jh2qvgn, child number 0                                           
-------------------------------------                                           
select  /*+   RULE */  * from bic_code b where rownum < 100                     
                                                                                
Plan hash value: 2632626061                                                     
                                                                                
---------------------------------------                                         
| Id  | Operation          | Name     |                                         
---------------------------------------                                         
|   0 | SELECT STATEMENT   |          |                                         
|*  1 |  COUNT STOPKEY     |          |                                         
|   2 |   TABLE ACCESS FULL| BIC_CODE |                                         
---------------------------------------                                         
                                                                                
Query Block Name / Object Alias (identified by operation id):                   
-------------------------------------------------------------                   
                                                                                
   1 - SEL$1                                                                    
   2 - SEL$1 / B@SEL$1                                                          
                                                                                
Outline Data                                                                    

PLAN_TABLE_OUTPUT                                                               
--------------------------------------------------------------------------------
-------------                                                                   
                                                                                
  /*+                                                                           
      BEGIN_OUTLINE_DATA                                                        
      IGNORE_OPTIM_EMBEDDED_HINTS                                               
      OPTIMIZER_FEATURES_ENABLE('11.2.0.3')                                     
      DB_VERSION('11.2.0.3')                                                    
      RBO_OUTLINE                                                               
      OUTLINE_LEAF(@"SEL$1")                                                    
      FULL(@"SEL$1" "B"@"SEL$1")                                                
      END_OUTLINE_DATA                                                          
  */                                                                            
                                                                                
Predicate Information (identified by operation id):                             
---------------------------------------------------                             
                                                                                
   1 - filter(ROWNUM<100)                                                       
                                                                                
Column Projection Information (identified by operation id):                     
-----------------------------------------------------------                     
                                                                                

PLAN_TABLE_OUTPUT                                                               
--------------------------------------------------------------------------------
   1 - "B"."BIC_BANK_CODE"[VARCHAR2,8],                                         
       "B"."BIC_BRANCH_CODE"[VARCHAR2,3], "B"."BIC_NAME"[VARCHAR2,35],          
       "B"."IC_BIC_CAC_TO_CAC_AUTH"[VARCHAR2,3],                                
       "B"."IC_BIC_TYPE"[VARCHAR2,3], "B"."BIC_END_DATE"[DATE,7]                
   2 - "B"."BIC_BANK_CODE"[VARCHAR2,8],                                         
       "B"."BIC_BRANCH_CODE"[VARCHAR2,3], "B"."BIC_NAME"[VARCHAR2,35],          
       "B"."IC_BIC_CAC_TO_CAC_AUTH"[VARCHAR2,3],                                
       "B"."IC_BIC_TYPE"[VARCHAR2,3], "B"."BIC_END_DATE"[DATE,7]                
                                                                                
Note                                                                            
-----                                                                           
   - rule based optimizer used (consider using cbo)

Si quelqu'un pouvait me faire une petite synthèse sur cette histoire, je lui serais bien reconnaissant.


[EDIT 20/04/2016 14:16]
Ah, je poursuis mes tests et je suis GRANDEMENT rassuré par ce que je vois

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
select count(*) from bic_code;
select * from table(dbms_xplan.display_cursor(null, null, 'basic'));

COUNT(*)
----------
    161644
1 row selected.

PLAN_TABLE_OUTPUT                                                               
--------------------------------------------------------------------------------
EXPLAINED SQL STATEMENT:                                                        
------------------------                                                        
select count(*) from bic_code                                                   
                                                                                
Plan hash value: 3562512118                                                     
                                                                                
----------------------------------------                                        
| Id  | Operation        | Name        |                                        
----------------------------------------                                        
|   0 | SELECT STATEMENT |             |                                        
|   1 |  SORT AGGREGATE  |             |                                        
|   2 |   INDEX FULL SCAN| PK_BIC_CODE |                                        
----------------------------------------                                        

14 rows selected.

Utilisation du hint FULL --> voilà un résultat qui me plait!
Visiblement l'utilisation de ce paramètre IGNORE_OPTIM_EMBEDDED_HINTS n'est pas très claire.
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
select /*+ FULL(bic_code) */ count(*) from bic_code;  
select * from table(dbms_xplan.display_cursor(null, null, 'basic'));


  COUNT(*)
----------
    161644
1 row selected.

PLAN_TABLE_OUTPUT                                                               
--------------------------------------------------------------------------------
EXPLAINED SQL STATEMENT:                                                        
------------------------                                                        
select /*+ FULL(bic_code) */ count(*) from bic_code                             
                                                                                
Plan hash value: 1320553103                                                     
                                                                                
---------------------------------------                                         
| Id  | Operation          | Name     |                                         
---------------------------------------                                         
|   0 | SELECT STATEMENT   |          |                                         
|   1 |  SORT AGGREGATE    |          |                                         
|   2 |   TABLE ACCESS FULL| BIC_CODE |                                         
---------------------------------------                                         

14 rows selected.