Je sais que c'est une question ultra courante, tapez pas de suite....
J'ai trois tables:
A (col_id number not null, col1 number not null, col2 varchar2 null)
==> 100 000 lignes
B (col_id number not null, col2 varchar2 not null)
==> 500 lignes
C (col_id number not null, col2 varchar2 not null)
==> pas de lignes
Voilà la requete:
select distinct B.col_id, A.col_id
from tableA A, tableB B
where A.col1 = 0 and NVL(A.col2, ' ')=B.col2
union
select distinct C.col_id, A.col_id
from tableA A, tableC C
where A.col1 = 0 and NVL(A.col2, ' ')=C.col2;
J'ai mis deux index dans la table A, le premier sur col1 et le deuxième est un index de fonction sur NVL (col2).
Col1 ne peut prendre que 3 valeurs: 0,1 et 2 , la valeur utilisée dans la requête (donc 0) ne concerne qu'un quart de la table, donc est très discriminante.
Aucun des ces deux indexs n'est utilisés, même en tentant d'en forcer l'utilisation avec un hint...
Les stats sont à jour (j'ai tenté en mode estimate et en mode compute) et les indexs rebuildés....
Deux ou trois fois, lors de mes tests, Oracle a utilisé les indexs et le temps a été divisé par 3.
A vrai dire, je ne vois pas comment un table full scan pourrait être plus efficace qu'un index sur 1/4 de la table?
Ah oui, je précise que l'index est un b-tree car ma boite ne veut utiliser que la version standard d'oracle.
Encore une précision, le nombre de lignes dans mes tables n'est pas opérationnel, les ordres de grandeur sont plutot:
A ==> 1 millions
B et C ==> 2-3 millions
J'espère que ce n'est pas ca qui fausse mes tests?
De même, je me demandais si Oracle recalculais vraiment le plan d'execution à chaque fois que je teste ma requête, ou s'il ne réutilisait pas ce qu'il avait déjà dans son cache? Auquel cas, ce n'est pas la peine de rajouter ou d'enlever des indexs, il ne le "verra" pas.
Qq aurait-il une idée?
Merci!
Partager