عدم استفاده از ایندکس در دستور like
برای جلوگیری از full table scan در شرط های استفاده شده از Like %% در اوراکل باید از Oracle Text utility یا همان Oracle context – Oracle Text indexes در اوراکل استفاده نماییم.
بطور مثال:
👉connect saeed;
CREATE TABLE test AS SELECT * FROM all_objects;
👉connect saeed;
CREATE TABLE test AS SELECT * FROM all_objects;
👉connect / as sysdba
grant execute on ctx_ddl to public;
grant execute on ctx_ddl to public;
👉connect saeed;
begin
ctx_ddl.create_preference('SUBSTRING_PREF', 'BASIC_WORDLIST');
ctx_ddl.set_attribute('SUBSTRING_PREF','SUBSTRING_INDEX','TRUE');
end;
begin
ctx_ddl.create_preference('SUBSTRING_PREF', 'BASIC_WORDLIST');
ctx_ddl.set_attribute('SUBSTRING_PREF','SUBSTRING_INDEX','TRUE');
end;
👉create index test_idx on test(object_type) indextype is ctxsys.context parameters ('wordlist SUBSTRING_PREF memory 50m');
👉set autotrace trace explain
select * from test where contains (OBJECT_TYPE,'%YOUR_WORD%') > 0
select * from test where contains (OBJECT_TYPE,'%YOUR_WORD%') > 0
همانطور که مشاهده می کنیم در Execution Plan اوراکل از ایندکس استفاده شده است.
هر از گاهی باید Index re-synchronization انجام شود که می توانید بصورت Job های شبانه این عمل را انجام دهید:
SQL> EXEC CTX_DDL.SYNC_INDEX('test_idx');
SQL> EXEC CTX_DDL.OPTIMIZE_INDEX('test_idx','FULL');
SQL> EXEC CTX_DDL.SYNC_INDEX('test_idx');
SQL> EXEC CTX_DDL.OPTIMIZE_INDEX('test_idx','FULL');
روش های دیگر همانطور که قبلا هم اشاره شده بود استفاده از Index hint در اوراکل می باشد.
CREATE INDEX test_idx ON test(object_type);
SELECT /*+INDEX(OBJECT_TYPE,test_idx )*/ from test where OBJECT_TYPE LIKE '%ABC%';
SELECT /*+INDEX(OBJECT_TYPE,test_idx )*/ from test where OBJECT_TYPE LIKE '%ABC%';
روش بعدی Case insensitive searching در اوراکل می باشد.
create index upper_full_name on customer ( upper(full_name));
alter session set NLS_COMP=ANSI;
alter session set NLS_SORT=GENERIC_BASELETTER;
select * from customer where full_name = 'Don Burleson'
alter session set NLS_COMP=ANSI;
alter session set NLS_SORT=GENERIC_BASELETTER;
select * from customer where full_name = 'Don Burleson'