1. 程式人生 > >由淺入深學優化之like‘%%’坑爹寫法

由淺入深學優化之like‘%%’坑爹寫法

耐心 rom 分享 http xxxx lec HERE usr 應用

某交易系統,監控告警有長SQL產生,腳本查詢大於5分鐘的長SQL。腳本內容如下:
SQL Text : select from ( select tmp_page., rownum row_id from ( SELECT
UUID,USR_ID,IN_MNO,MNO,xxxx,xxx,xxx,xxxxx,xxxxx
FROM ABC.MEC_IF
WHERE MNO LIKE :1
order by UUID desc ) tmp_page where rownum <= :2 ) where
row_id > :3

Bind Variables :
1 - (VARCHAR2(128)):%836305057320133%

2 - (NUMBER):20
3 - (NUMBER):0

MNO like字段內容很長嗎?

15:09:16 SYS@bapdb1(bapdb1)> SELECT mno from BAP.T_BAP_MEC_IF where rownum<=2;

MNO

500591001000000
500591001000001
是不是很蛋有點疼,興許開發大爺心情不爽,非要搞事情。耐心看一下執行計劃,丫肯定走偏了。
技術分享圖片

該表的PK是UUID列,MNO列也有自己的索引,最爛的執行計劃,索引全掃描外加回表,由於受ORDER BY UUID DESC影響,oracle錯誤的選擇了index掃描

技術分享圖片
技術分享圖片

當一個列出現在where條件中,該列沒有創建索引,並且選擇性大於20%,那麽該列就必須創建索引

其實此類SQL優化起來比較簡單
EXPLAIN PLAN FOR select from ( select tmp_page., rownum row_id from ( SELECT
UUID,USR_ID,IN_MNO,MNO,xxxx,xxx,xxx,xxxxx,xxxxx
FROM ABC.MEC_IF
WHERE MNO LIKE ‘836305057320133%‘
order by UUID desc ) tmp_page where rownum <= 20 ) where
row_id > 0;
技術分享圖片

1。盡量不要使用 like ‘%%‘
2。對於 like ‘%‘ (不以 % 開頭),Oracle可以應用 colunm上的index

3。對於 like ‘%…‘ 的 (不以 % 結尾),可以利用reverse + function index 的形式,變化成 like ‘%‘
4.非用like‘%%‘不可時,使用Oracle內部函數:INSTR()解決。
例子:select * from emp where instr(job,‘RE‘)>0 and instr(ename,‘A‘)>0 and instr(mgr,‘3‘)>0;

由淺入深學優化之like‘%%’坑爹寫法