Oracle FAQ Your Portal to the Oracle Knowledge Grid
HOME | ASK QUESTION | ADD INFO | SEARCH | E-MAIL US
 

Home -> Community -> Usenet -> c.d.o.misc -> Re: Function based index not being used

Re: Function based index not being used

From: Barbara Boehmer <baboehme_at_hotmail.com>
Date: 8 Jul 2005 18:46:36 -0700
Message-ID: <1120873596.875750.326760@z14g2000cwz.googlegroups.com>


It looks like my post got a little messed up. That'll teach me to preview first. Here is another attempt, since I don't see an option to edit or delete. If this doesn't come out right, I'll just leave it at that and hope you can decipher it.

Bruce,

I just noticed that your function is returning a raw datatype. I ran into this problem once before. I forgot that, when you are creating a function-based index on a function that returns a raw datatype, you must constrain the return value using substr, in order for the index to be used. Please see the revised demonstration below, in which I used a function that returns a raw datatype and two indexes, one without substr and one with substr. The one without substr does not use the index, but the one with substr in both the index creation and query does use the index.

scott_at_ORA92> CREATE USER otherUser IDENTIFIED BY otherUserPassword   2 /

User created.

scott_at_ORA92> GRANT CONNECT, RESOURCE TO otherUser   2 /

Grant succeeded.

scott_at_ORA92> CONNECT otherUser/otherUserPassword Connected.
scott_at_ORA92> @ LOGIN
scott_at_ORA92> SET ECHO OFF

GLOBAL_NAME



otheruser_at_ORA92

otheruser_at_ORA92> create or replace function myFunction( p_str in varchar2 )
  2 return raw deterministic
  3 as
  4 l_data varchar2(255);
  5 begin

  6  	 l_data := rpad( p_str, (trunc(length(p_str)/8)+1)*8, chr(0) );
  7  	     return dbms_obfuscation_toolkit.DESEncrypt
  8  		( input => utl_raw.cast_to_raw(l_data),
  9  			      key => utl_raw.cast_to_raw('MagicKey') );
 10 end;
 11 /

Function created.

otheruser_at_ORA92> SHOW ERRORS
No errors.
otheruser_at_ORA92> CONNECT scott/tiger
Connected.
otheruser_at_ORA92> @ LOGIN
otheruser_at_ORA92> SET ECHO OFF

GLOBAL_NAME



scott_at_ORA92

scott_at_ORA92> create table indxtest as select * from all_objects where rownum <= 1000
  2 /

Table created.

scott_at_ORA92> ALTER SESSION SET QUERY_REWRITE_ENABLED=TRUE   2 /

Session altered.

scott_at_ORA92> ALTER SESSION SET QUERY_REWRITE_INTEGRITY=TRUSTED   2 /

Session altered.

scott_at_ORA92> create index indxtest_func_idx1   2 on indxtest (otherUser.myFunction (object_name))   3 /

Index created.

scott_at_ORA92> create index indxtest_func_idx2   2 on indxtest (substr (otherUser.myFunction (object_name), 1, 2000))   3 /

Index created.

scott_at_ORA92> EXECUTE DBMS_STATS.GATHER_TABLE_STATS ('SCOTT', 'INDXTEST') PL/SQL procedure successfully completed.

scott_at_ORA92> SET AUTOTRACE ON EXPLAIN
scott_at_ORA92> select *
  2 from indxtest
  3 where otherUser.myFunction (object_name) = 'aa'   4 /

no rows selected

Execution Plan


   0 SELECT STATEMENT Optimizer=CHOOSE (Cost=3 Card=10 Bytes=1280)    1 0 TABLE ACCESS (FULL) OF 'INDXTEST' (Cost=3 Card=10 Bytes=1280)

scott_at_ORA92> select *
  2 from indxtest
  3 where substr (otherUser.myFunction (object_name), 1, 2000) = 'aa'   4 /

no rows selected

Execution Plan


   0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1 Bytes=128)    1 0 TABLE ACCESS (BY INDEX ROWID) OF 'INDXTEST' (Cost=2 Card=1 Bytes=128)

   2 1 INDEX (RANGE SCAN) OF 'INDXTEST_FUNC_IDX2' (NON-UNIQUE) (Cost=1 Card=1)

scott_at_ORA92> Received on Fri Jul 08 2005 - 20:46:36 CDT

Original text of this message

HOME | ASK QUESTION | ADD INFO | SEARCH | E-MAIL US