SQL 使用like '%ABC' 和 like '%ABC%'的優化

通常狀況下,sql中使用col_name like 'ABC%‘的狀況才能使用到col_name字段上的索引,這種狀況再也不贅述。
sql


若是是col_name like '%ABC%'的狀況,可否使用索引,怎樣才能使用索引?數組

答案是:可使用索引,可是須要改寫SQL並建立reverse函數索引。性能優化


1、col_name like '%ABC'時的優化方法微信


Test case:
oracle

    Create table t1 as select * from dba_objects;函數

    Create index idx_t1_objectname1 on t1(object_name);性能

百分號在後面,可使用索引:優化

    select object_name from t1 where object_name like ‘DBA%';spa

百分號在前面,不能使用索引:.net

    select object_name from t1 where object_name like '%LIB';


解決方法:

create index idx_t1_objectname2 on t1(reverse(object_name));

select object_name from t1 where reverse(object_name) like reverse('%LIB');

執行計劃:




2、col_name like '%ABC%'時的優化方法

通常認爲這種狀況是不能使用索引的,但仍是有一些優化方法可使用。


三種狀況:

一、ABC始終從字符串開始的某個固定位置出現,能夠建立函數索引進行優化

二、ABC始終從字符串結尾的某個固定位置出現,能夠建立函數組合索引進行優化

三、ABC在字符串中位置不固定,能夠經過改寫SQL進行優化


狀況一、先建立substr函數索引,再使用like ‘ABC%’。

假如ABC從字符串第五位出現:

Test Case:

create index idx_substr_t1_objname on t1 (substr(object_name,5,30));

select object_id,object_type,object_name from t1

where substr(object_name,5,30) like 'TAB%';


狀況二、先建立reverse+substr組合函數索引,再使用like reverse‘%ABC’。

假如ABC從字符串倒數第五位出現:

Test Case:

Create index idx_t1_reverse2 on t1(reverse(substr(object_name,1,length(object_name)-4)));

select object_id,object_name,object_type from t1 

where reverse(substr(object_name,1,length(object_name)-4)) like reverse('%TAB_COL');


狀況三、這種狀況須要like的字段上存在普通索引,主要在SQL的寫法上作改進。

原來的SQL是這樣寫的:

Select object_id,object_type,object_name from t1

where object_name like '%ABC%‘;


改寫後的SQL是這樣的:

Select object_id ,object_type,object_name from t1 

Where object_name in

(select object_name from t1 where object_name like ‘%ABC%’);


Test Case:

create index idx_t1_object_name on t1 (object_name);


Select object_id,object_type,object_name from t1

where object_name like '%TABCOL%';

此時SQL的執行計劃是t1 表作全表掃描。


Select object_id,object_type,object_name from t1

Where object_name in

(select object_name from t1 where object_name like '%TABCOL%');


改寫後的SQL執行計劃是索引全掃描加索引回表操做:


優化原理:

      用索引全掃描取表明的全掃描。由於索引全掃描的代價是全表掃描的1/N (即索引塊數與數據塊數的比例),表越大,優化效果越明顯。

改寫後SQL的執行計劃,根據索引再回表的代價要看符合條件的記錄數多少:若是in子查詢返回的記錄數不多,那麼優化的效果就至關於效率提升了N倍;若是in子查詢返回的記錄數較多,兩種SQL的性能區別就不是很明顯了。




本文分享自微信公衆號 - 老虎劉談oracle性能優化(sql_tigerliu)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索