一.like查詢與索引mysql
在oracle裏的一個超級大的表中,咱們的where條件的列有建索引的話,會走索引惟一掃描INDEX UNIQUE SCAN。如select * from table where code = 'Cod25',而以下這些語句哪些會走索引呢?sql
經驗證:
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
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的記錄
在執行的時候,執行計劃顯示,消耗值,io值,cpu值均很是大,緣由是like後面前模糊查詢致使索引失效,進行全表掃描。
解決方法:這種只有前模糊的sql能夠改造以下寫法
使用翻轉函數+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.通常的索引:
當執行SELECT * FROM TABLE1 WHERE COLUMN1 = XXX 時會用到索引。
2.函數索引:
當執行SELECT * FROM TABLE1 WHERE SUBSTR(COLUMN1,0,5) = XXX 時會用到索引。但執行SELECT * FROM TABLE1 WHERE COLUMN1 = XXX時是不會用到索引的。通常狀況下是最好不用建函數索引。
原文連接:https://blog.csdn.net/bolg_hero/article/details/77606734