Bonjour,
Suite à une requête basique de type :
La table t1 contient environ 1.3 million de lignes.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 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
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.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 Select density from user_tab_col_statistics where table_name = 'TABLE1' and column_name = 'COL3'
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
NB2 : Mon Oracle : Oracle9i Release 9.2.0.4.0
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 DBMS_STATS.gather_table_stats(ownname => 'SYS' , tabname => 'TABLE1', cascade => true, estimate_percent => 100,granularity => 'ALL', degree => 1);
Partager