like查詢與索引

2021-07-05 08:56:39 字數 3062 閱讀 4244

一.like查詢與索引

在oracle裡的乙個超級大的表中,我們的where條件的列有建索引的話,會走索引唯一掃瞄index unique scan。如select * from table where code = 'cod25',而如下這些語句哪些會走索引呢?

sql**  

select * from

table

where code like

'code2%'

select * from

table

where code like

'%ode2%'

select * from

table

where code like

'%ode2'

經驗證:

select * from table where code like 'cod2%'會走索引,且走的是index range scan,而這樣寫like '%***'或'%***%'不會走索引,感覺就像組合索引一樣,直接用索引第乙個欄位會走索引,而用索引第二個欄位則不會走索引。

當然,如果select * from table where code like 'cod%' 查詢的結果就是所有記錄,走索引和full table scan的結果是一樣的,所以也將是全表掃瞄。可以換成select * from table where code like 'code2%'或者 select count(*) from table where code like 'cod%'試試,應該不會是全表掃瞄。

****

二.優化like查詢

1.經上面測試,like查詢結果如下:

a.like %keyword    索引失效,使用全表掃瞄。但可以通過翻轉函式+like前模糊查詢+建立翻轉函式索引=走翻轉函式索引,不走全表掃瞄。如where reverse(code) like reverse('%code2')

b.like keyword%    索引有效。  

c.like %keyword%   索引失效,也無法使用反向索引。

2.優化like查詢:

a.使用其它函式來進行模糊查詢,如果出現的位置大於0,表示包含該字串,查詢效率比like要高。

1)在oracle中,可以用instr,這樣查詢效果很好,速度很快。

sql**  

select

count(*) from

table t where instr(t.code,'cod2%') > 0  

2)在mysql中,可以用locate和position函式,如table.field like '%aaa%'可以改為locate('aaa', table.field) > 0或position('aaa' in table.field)>0。

locate(substr,str)、position(substr in str):返回子串 substr 在字串 str 中第一次出現的位置。如果子串 substr 在 str 中不存在,返回值為 0。

3)在sql server中,可以給字段建立全文索引,用contains來檢索資料,contains用法,可以參考:

b.查詢%xx的記錄  

sql**  

select

count(c.c_ply_no) as

count

from policy_data_all c, item_data_all i  

where c.c_ply_no = i.c_ply_no  

and i.c_lcn_no like 』%245′  

在執行的時候,執行計畫顯示,消耗值,io值,cpu值均非常大,原因是like後面前模糊查詢導致索引失效,進行全表掃瞄。

解決方法:這種只有前模糊的sql可以改造如下寫法

sql**  

select

count(c.c_ply_no) as

count

from policy_data_all c, item_data_all i  

where c.c_ply_no = i.c_ply_no  

and reverse(i.c_lcn_no) like reverse('%245')  

使用翻轉函式+like前模糊查詢+建立翻轉函式索引=走翻轉函式索引,不走全掃瞄。有效降低消耗值,io值,cpu值這三個指標,尤其是io值的降低。

建函式索引:create index p_idx on table(instr(code,'code2'));需進一步說明的是,這樣的話,只有where instr(code,'code2')才會走index range scan,其它如where instr(code, 'code3')會走index fast full scan甚至table access full。

另外,select * from table where upper(code) = 'abcd',會走table access full。如果建函式索引create index idx_upper on table(upper(code));之後,將會是index range scan,如下所示:

ps:一般索引和函式索引的區別

1.一般的索引:

sql**  

create

index p_idx on table1(column1);  

當執行select * from table1 where column1 = *** 時會用到索引。

2.函式索引:

sql**  

create

index p_idx on table1(substr(column1,0,5));  

當執行select * from table1 where substr(column1,0,5) = *** 時會用到索引。但執行select * from table1 where column1 = ***時是不會用到索引的。一般情況下是最好不用建函式索引。

LIKE查詢與索引的不解之謎

like keyword 索引失效,使用全表掃瞄。但可以通過翻轉函式 like前模糊查詢 建立翻轉函式索引 走翻轉函式索引,不走全表掃瞄。like keyword 索引有效。like keyword 索引失效,也無法使用反向索引。查詢 xx的記錄 select count c.c ply no as...

like查詢如何有索引效果

一.like查詢與索引 在oracle裡的乙個超級大的表中,我們的where條件的列有建索引的話,會走索引唯一掃瞄index unique scan。如select from table where code cod25 而如下這些語句哪些會走索引呢?sql select from table wh...

like查詢索引失效問題與解決辦法

一.like查詢與索引 在oracle裡的乙個超級大的表中,我們的where條件的列有建索引的話,會走索引唯一掃瞄index unique scan。如select from table where code cod25 而如下這些語句哪些會走索引呢?sql select from table wh...