Problème avec le CBO d'Oracle sur filtre simple
Bonjour,
Suite à une requête basique de type :
Code:
1 2 3 4 5 6
| Select t1.col1, t1.col2,...
from table1 t1 inner join table2 t2
left outer join table3 t3
etc..
where [filtre divers]
and t1.col3 = 'toto' |
La table t1 contient environ 1.3 million de lignes.
La col3 contient exactement 18 valeurs distinctes, et 1.2 million de lignes correspondent à col3 = 'toto'. Autant dire que la requête devrait taper un full scan sur table1.
Le problème est qu'avec le filtre "and t1.col3 = 'toto'", l'explain plan explose avec l'utilisation d'index non pertinent, et la requete ne répond plu.
Si j'enleve ce filtre, l'explain plan fait son boulot en me full scannant ce qu'il faut et en hash outer joignant comme il faut, et me repond en 10 minutes.
Je suis allé faire un
Code:
1 2 3 4
| Select density
from user_tab_col_statistics
where table_name = 'TABLE1'
and column_name = 'COL3' |
Et j'ai donc 0.05555 = 1/18 (CF http://marius-nitu.developpez.com/tu...-calcule-cout/). J'ai peur que le CBO réagit comme si ma col3 etait parfaitement distribué, ce qui est tres tres loin d'etre le cas.
Pour linstant je contourne le probleme avec un hint pour fullscanner ma table1, mais j'aimerais bien savoir comment dire à oracle de faire les stats sur cette colonne en un peu plus intelligent !!
J'ai aussi tenter de créer un index sur COL3, pour 'ouvrir' les yeux au CBO, mais ca n'a pas mieux fonctionner, il s'entete a croire que la clause "t1.col3 = 'toto'" va lui ramener quelques lignes alors que ca va lui ramener la table entiere !
NB : ma commande pour passer les stats
Code:
1 2 3
| DBMS_STATS.gather_table_stats(ownname => 'SYS' ,
tabname => 'TABLE1',
cascade => true, estimate_percent => 100,granularity => 'ALL', degree => 1); |
NB2 : Mon Oracle : Oracle9i Release 9.2.0.4.0