前幾天,有個給運營商作維護的DBA小陳問:
sql
劉老師,我這個SQL不能使用索引,你幫我確認一下,是否是遇到了「隱式類型轉換」?而後發了一個執行計劃的最後部分給我看:性能優化
Peeked Binds (identified by position):微信
--------------------------------------oracle
1 - :V1 (VARCHAR2(30), CSID=852): '4000874'ide
2 - :V2 (VARCHAR2(30), CSID=852): '4000874'性能
Predicate Information (identified by operation id):優化
---------------------------------------------------spa
4 - filter(("RATABLE_RESOURCE_ID"=TO_NUMBER(:V1) OR "TRANSFER_RESOURCE_ID"=TO_NUMBER(:V2))).net
我說沒錯,確實是有隱式類型轉換。可是,這個隱式類型轉換倒是「無害」的,由於若是字段是number類型,綁定變量是varchar2類型,這種隱式類型轉換是不會影響SQL執行計劃的。而若是字段是varchar2類型,綁定變量是number類型,這種纔是最危險的。orm
小陳接下來發了完整的SQL,並告知第一個謂詞條件字段(紅色)上有主鍵:
SELECT
......
FROM hss.tb_bil_ratable_resource
WHERE ratable_resource_id = '4000874' OR transfer_resource_id = '4000874';
我一看SQL,立刻就明白是什麼緣由了:這個SQL若是要想使用索引,必須還要建立另外一個謂詞條件字段(transfer_resource_id)上的索引。
小陳建立完索引後很快就發消息說搞定了!
解釋:
由於兩個謂詞條件之間的關係是OR,而不是一般見到的AND,若是是AND,不用建立另外一個字段上的索引就可使用已經存在的主鍵索引。
總結:
這個SQL雖然很是簡單,可是若是沒有理解OR和AND的區別,仍是會比較迷惑。並且客戶以前被隱式類型轉換折騰過幾回,此次發現一個,惋惜卻不是根因。
本文分享自微信公衆號 - 老虎劉談oracle性能優化(sql_tigerliu)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。