caso). Bom, a ideia entao foi criar um indice baseado em funcao na qual a mesma limitaria o tamanho da coluna VARCHAR2(4000) para o tamanho da coluna numerica da tabela T1 (EMP_CODE). Como o tamanho da coluna EMP_CODE da tabela T1 e NUMBER(15), irei criar um indice de funcao SUBSTR(VALUE,1,15) na tabela T2. Como na instrucao SQL existem outros filtros, irei criar 2 indices conforme demonstrado abaixo.SQL> create index idx_name_hash on t1 (name,hash) tablespace tbs_indx noparallel;SQL> create index idx_substr_value_depcode on t2 (substr(value,1,15),dep_code) tablespace tbs_indx noparallel; Apos criados os indices e alterada a instrucao SQL para utilizar a funcao SUBSTR, segue abaixo o plano de execucao gerado:SQL> SELECT ROWNUM id, 2 NAME, 3 HASH, 4 EMP_CODE, 5 DEP_CODE, 6 VALUE 7 FROM T1 A, T2 B 8 WHERE A.NAME = 'file.pdf' 9 AND A.HASH = 'F847F75E563EC732C61DB76C239BC34C' 10 AND SUBSTR(B.VALUE,1,15) = A.EMP_CODE 11 AND B.DEP_CODE = 13; ID NAME HASH EMP_CODE DEP_CODE VALUE------- -------------------- -------------------------------- ---------- ---------- -------------- 1 file.pdf F847F75E563EC732C61DB76C239BC34C 363423 23650082 363423 2 file.pdf F847F75E563EC732C61DB76C239BC34C 363427 23652704 363427 3 file.pdf F847F75E563EC732C61DB76C239BC34C 363428 23653157 363428 4 file.pdf F847F75E563EC732C61DB76C239BC34C 363430 23654312 363430 5 file.pdf F847F75E563EC732C61DB76C239BC34C 363770 23759064 363770 6 file.pdf F847F75E563EC732C61DB76C239BC34C 363793 23765071 363793 7 file.pdf F847F75E563EC732C61DB76C239BC34C 372161 24406201 372161 8 file.pdf F847F75E563EC732C61DB76C239BC34C 372165 24406453 372165 9 file.pdf F847F75E563EC732C61DB76C239BC34C 372169 24406707 372169 10 file.pdf F847F75E563EC732C61DB76C239BC34C 468922 33918406 468922 11 file.pdf F847F75E563EC732C61DB76C239BC34C 468926 33918658 46892611 linhas selecionadas.Decorrido: 00:00:42Plano de Execucao----------------------------------------------------------Plan hash value: 540149683------------------------------------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |------------------------------------------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 3 | 258 | 103K (1)| 00:20:42 || 1 | COUNT | | | | | ||* 2 | HASH JOIN | | 3 | 258 | 103K (1)| 00:20:42 || 3 | TABLE ACCESS BY INDEX ROWID| T1 | 3 | 177 | 6 (0)| 00:00:01 ||* 4 | INDEX RANGE SCAN | IDX_NAME_HASH | 3 | | 3 (0)| 00:00:01 ||* 5 | TABLE ACCESS FULL | T2 | 5251K| 88M| 103K (1)| 00:20:42 |------------------------------------------------------------------------------------------------------------Predicate Information (identified by operation id):--------------------------------------------------- 2 - access("A"."EMP_CODE"=TO_NUMBER(SUBSTR("VALUE",1,15))) 4 - access("A"."NAME"='file.pdf' AND "A"."HASH"='F847F75E563EC732C61DB76C239BC34C') 5 - filter("B"."DEP_CODE"=13) Foi possivel verificar acima que a instrucao SQL executou em 42 segundos, o que e pessimo, e que o indice IDX_NAME_HASH foi utilizado. No entanto, o indice de funcao criado na tabela T2 nao foi usado e por isso esta sendo realizado uma operacao de TABLE ACCESS FULL na mesma em cerca de 5 milhoes de linhas ao realizar uma operacao de HASH JOIN. A questao e: porque o otimizador nao utilizou o indice de funcao? Apos alguns testes utilizando HINTS para forcar o uso do indice entre outras tentativas, consegui a tempo perceber que a resposta estava no proprio plano de execucao na secao "Predicate Information". E possivel perceber que o Oracle implicitamente converteu o tipo de dado utilizando a funcao TO_NUMBER de modo a fazer o JOIN com a coluna EMP_CODE que e NUMBER(15), o que e compreensivel. Neste caso, o problema pode ser resolvido com 2 opcoes: criar o indice como TO_NUMBER(SUBSTR(VALUE,1,15)) na tabela T1 ou utilizar a funcao TO_CHAR na coluna EMP_CODE como demonstrado abaixo:SQL>