一.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查詢與索引 在oracle裡的乙個超級大的表中,我們的where條件的列有建索引的話,會走索引唯一掃瞄index unique scan。如select from table where code cod25 而如下這些語句哪些會走索引呢?sql select from table wh...
like索引失效原因 索引失效的情況及原因定位
同事遇到乙個奇葩的問題,乙個表裡某個欄位建了索引,但是有的值走索引,有的值不走索引。因為一般情況乙個字段要麼完全不走索引,要麼走索引,怎麼會有的值走索引,有的不走索引。select 條件非常簡單,因為涉及到敏感資訊就不貼表結構了。例如select from order where status 2 ...
mysql模糊查詢索引失效問題及解決方案
我們在使用like 萬用字元時常常會引起索引失效的問題。這裡,我們討論一下like使用 的幾種情況 下列例子用到的索引 vc student name 一 like xx explain select from t student where vc student name like 王 二 lik...