lik模糊e查詢語句,索引使用效果詳解

一.like查詢與索引mysql

        在oracle裏的一個超級大的表中,咱們的where條件的列有建索引的話,會走索引惟一掃描INDEX UNIQUE SCAN。如select * from table where code = 'Cod25',而以下這些語句哪些會走索引呢?sql

Sql代碼   收藏代碼
  1. select * from table where code like 'Code2%'  
  2. select * from table where code like '%ode2%'  
  3. select * from table where code like '%ode2'  

經驗證:
        select * from table where code like 'Cod2%'會走索引,且走的是INDEX RANGE SCAN,而這樣寫like '%xxx'或'%xxx%'不會走索引,感受就像組合索引同樣,直接用索引第一個字段會走索引,而用索引第二個字段則不會走索引。oracle

        固然,若是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,這樣查詢效果很好,速度很快。spa

Sql代碼   收藏代碼
  1. 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。.net

        LOCATE(substr,str)、POSITION(substr IN str):返回子串 substr 在字符串 str 中第一次出現的位置。若是子串 substr 在 str 中不存在,返回值爲 0。3d

        3)在sql server中,能夠給字段創建全文索引,用contains來檢索數據,CONTAINS用法,能夠參考:http://bijian1013.iteye.com/blog/2232872code

        b.查詢%xx的記錄  

Sql代碼   收藏代碼
  1. select count(c.c_ply_no) as COUNT  
  2.   from Policy_Data_All c, Item_Data_All i  
  3.  where c.c_ply_no = i.c_ply_no  
  4.    and i.C_LCN_NO like ’%245′  

        在執行的時候,執行計劃顯示,消耗值,io值,cpu值均很是大,緣由是like後面前模糊查詢致使索引失效,進行全表掃描。
        解決方法:這種只有前模糊的sql能夠改造以下寫法

Sql代碼   收藏代碼
  1. select count(c.c_ply_no) as COUNT  
  2.   from Policy_Data_All c, Item_Data_All i  
  3.  where c.c_ply_no = i.c_ply_no  
  4.    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代碼   收藏代碼
  1. create index P_IDX ON TABLE1(COLUMN1);  

        當執行SELECT * FROM TABLE1 WHERE COLUMN1 = XXX 時會用到索引。

2.函數索引:

Sql代碼   收藏代碼
  1. CREATE INDEX P_IDX ON TABLE1(SUBSTR(COLUMN1,0,5));  

        當執行SELECT * FROM TABLE1 WHERE SUBSTR(COLUMN1,0,5) = XXX 時會用到索引。但執行SELECT * FROM TABLE1 WHERE COLUMN1 = XXX時是不會用到索引的。通常狀況下是最好不用建函數索引。

原文連接:https://blog.csdn.net/bolg_hero/article/details/77606734

相關文章
相關標籤/搜索