Bonjour a tous,
j'ai une petite question relative à une PK composée de 2 champs.

(oracle 11g sous windows)

J'ai cette requête:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
select /*+ gather_plan_statistics */ p.base
from productos p
INNER JOIN producto_color_defecto pf2 ON p.base = pf2.producto ;
Cette requête donne ce plan:

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
Plan hash value: 1553037060
 
----------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation             | Name                   | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Reads  |  OMem |  1Mem | Used-Mem |
----------------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |                        |      1 |        |  66171 |00:00:00.31 |    4697 |    178 |       |       |          |
 
PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------------------------------------------------------------------
|*  1 |  HASH JOIN            |                        |      1 |  60850 |  66171 |00:00:00.31 |    4697 |    178 |  2162K|  1648K| 3131K (0)|
|   2 |   TABLE ACCESS FULL   | PRODUCTO_COLOR_DEFECTO |      1 |  38962 |  38962 |00:00:00.06 |     106 |      0 |       |       |          |
|   3 |   INDEX FAST FULL SCAN| IDX_PRODUCTOS_BASE     |      1 |  68251 |  66319 |00:00:00.24 |    4591 |    178 |       |       |          |
----------------------------------------------------------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   1 - access("P"."BASE"="PF2"."PRODUCTO")
Petit full scan sur la table de droite (producto_color_defecto)

Le comportement "normal" pour moi ici serait utilisation des indexes et pas de full scan. Donc j'ai regardé les index et sur cette table j'ai ceci :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
CREATE UNIQUE INDEX PK_PRODUCTO_COLOR_DEFECTO ON PRODUCTO_COLOR_DEFECTO
(PRODUCTO, COLOR)
 
ALTER TABLE PRODUCTO_COLOR_DEFECTO ADD (
  CONSTRAINT PK_PRODUCTO_COLOR_DEFECTO
  PRIMARY KEY
  (PRODUCTO, COLOR)
  USING INDEX PK_PRODUCTO_COLOR_DEFECTO);
Il existe une PK sur l'id de la table de gauche.

Je me doute que c'est a cause de la PK combinée donc je crée ceci :

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
create table prd_color_def as select * from producto_color_defecto
 
CREATE INDEX PK_PROD_COLOR_DEF ON prd_color_def(PRODUCTO)
 
BEGIN
  SYS.DBMS_STATS.GATHER_TABLE_STATS (
      OwnName        => 'MONSCHEMA'
     ,TabName        => 'PRD_COLOR_DEF'
    ,Estimate_Percent  => 10
    ,Method_Opt        => 'FOR ALL COLUMNS SIZE 1'
    ,Degree            => 0
    ,Cascade           => FALSE
    ,No_Invalidate     => FALSE);
END;
/
Et la j’obtiens le plan que j’imaginais. Donc c'est bien à cause de la PK combinée ?
Pourquoi Oracle choisit de faire un full scan, le premier des champs de la PK étant celui utilisé dans la requête ?

Pour éviter le full scan, faut-il ajouter un index sur le champ productos seul ?? Oracle l'utilisera dans ce cas ?

D'avance merci