由淺入深學優化之like‘%%’坑爹寫法
阿新 • • 發佈:2020-10-19
某交易系統,監控告警有長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%
3 - (NUMBER):0
MNO like欄位內容很長嗎?
15:09:16 [email protected](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%,那麼該列就必須建立索引
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
4.非用like'%%'不可時,使用Oracle內部函式:INSTR()解決。
例子:select * from emp where instr(job,'RE')>0 and instr(ename,'A')>0 and instr(mgr,'3')>0;
轉載於:https://blog.51cto.com/yangjunfeng/2146052