Friday, January 16, 2009

INDEX USAGE WITH LIKE OPERATOR


INDEX USAGE WITH LIKE OPERATOR


I have seen many developers getting confused on index usage with like operator.

Few are of the feeling that index will be used and few are against this feeling.

Let’s see this with example:

SQL> create table sac as select * from all_objects;

Table created.

SQL> create index sac_indx on sac(object_type);I

ndex created.

SQL> set autotrace trace explain

SQL> select * from sac where object_type='TAB%';

Execution Plan

----------------------------------------------------------
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=1 Card=1 Bytes=128)1

0 TABLE ACCESS (BY INDEX ROWID) OF 'SAC' (TABLE) (Cost=1 Card=1 Bytes=128)

2 1 INDEX (RANGE SCAN) OF 'SAC_INDX' (INDEX) (Cost=1 Card=1)

Above example shows that using % wild card character towards end probe an Index search.

But if it is used towards end, it will not be used. And sensibly so, because Oracle doesn’t know which data to search, it can start from ‘A to Z’ or ‘a to z’ or even 1 to any number.See this.

SQL> select * from sac where object_type like '%ABLE';

Execution Plan
----------------------------------------------------------0
SELECT STATEMENT Optimizer=ALL_ROWS (Cost=148 Card=1004 Bytes=128512)1
0 TABLE ACCESS (FULL) OF 'SAC' (TABLE) (Cost=148 Card=1004 Bytes=128512)

Now how to use the index if you are using Like operator searches. The answer is Domain Indexes.

See the following example:

SQL> connect / as sysdba

Connected.

SQL> grant execute on ctx_ddl to public;

Grant succeeded.

SQL> connect sac/******

Connected.

SQL> begin2 ctx_ddl.

create_preference('SUBSTRING_PREF',3 'BASIC_WORDLIST');

4 ctx_ddl.set_attribute('SUBSTRING_PREF',

5 'SUBSTRING_INDEX','TRUE');

6 end;

78 /PL/SQL procedure successfully completed.

SQL>SQL> drop index sac_indx;Index dropped.

SQL> create index sac_indx on sac(object_type)

indextype is ctxsys.context parameters ('wordlist SUBSTRING_PREF memory 50m');

Index created.

SQL> set autotrace trace exp

SQL> select * from sac where contains (OBJECT_TYPE,'%PACK%')

> 02 /Execution Plan

----------------------------------------------------------

0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=8 Card=19 Bytes=1786)1

0 TABLE ACCESS (BY INDEX ROWID) OF 'SAC' (TABLE) (Cost=8 Card=19 Bytes=1786)

2 1 DOMAIN INDEX OF 'SAC_INDX' (INDEX (DOMAIN)) (Cost=4)

In this case the index is getting used.

Conclusion=============For proximity, soundex and fuzzy searchs, use domain indexes.

No comments:

View My Stats