2016-06-29 2 views
0

J'ai cette requêtesur table partitionnée ne favorise pas les performances avec une fonction dans laquelle l'article

select col1,col2, x.id pk 
/*+ INDEX (some_index_on_col4)*/ 
from tbl1 y 
,tbl2 x 
where col2 = 'some_value' and col3 = 'U' 
and x.col4 = dbms_lob.substr(REPLACE(y.PK_DATA,'"',''), 100, 1) 
; 

la requête est très lent, et quand je lui explique le plan, il montre que l'indice n'est pas utilisé mais une analyse complète de la table est utilisée à la place, si je retire

dbms_lob.substr(REPLACE(y.PK_DATA,'"',''), 100, 1) 

et dire au lieu

x.col4 = 3456 

il fonctionne très bien, comment puis-je améliorer cela?

N.B. : Tbl2 est partitionné

+0

Vous pouvez également poster des plans d'exécution pour les deux requêtes comme décrit [ici] (http://stackoverflow.com/questions/34975406/how-to-describe-performance-issue-in-relational-database?answertab=active#tab-top) –

+1

Lorsque vous le modifiez à 'x.col4 = 3456' alors Oracle sait qu'il n'y aura qu'une seule valeur x.col4 d'intérêt (3456) et peut donc utiliser clairement l'index. Avec 'dbms_lob.substr (REPLACE (y.PK_DATA, '"', ''), 100, 1) 'il pourrait y avoir beaucoup de valeurs x.col4 différentes qui sont sélectionnées - peut-être même ** toutes ** - alors le l'optimiseur peut décider qu'un balayage complet est préférable, –

+0

effectivement il n'y avait pas de correspondance et c'est pourquoi l'index n'a pas été utilisé car un balayage complet a été effectué de toute façon ... mais quand il y a une correspondance, l'index est utilisé –

Répondre

0

en fait il n'y avait pas de match et c'est la raison pour laquelle l'indice n'a pas été utilisé comme une analyse complète a été réalisée quelque façon ... mais quand il y a un match, l'indice est utilisé

1

Une différence évidente (et la cause offen de ne pas utiliser index) est que le résultat de dbms_lob.substr(REPLACE(y.PK_DATA,'"',''), 100, 1) est VARCHAR, pas NUMBER comme 3456.

Si possible, transformez-le avec to_number.

Mais vous n'obtiendrez pas le même plan que pour 3456 parce que c'est constant; la requête d'origine utilise y.PK_DATA.

+0

merci, ça a aidé un peu, mais le plan d'exécution est toujours en train de dire qu'il fait un scan complet n'utilisant pas l'index –