天天看點

第一篇 熱身--隐式類型轉換還是其他?

前幾天,有個給營運商做維護的DBA小陳問:

劉老師,我這個SQL不能使用索引,你幫我确認一下,是不是遇到了“隐式類型轉換”?然後發了一個執行計劃的最後部分給我看:

Peeked Binds (identified by position):

--------------------------------------

1 - :V1 (VARCHAR2(30), CSID=852): '4000874'

2 - :V2 (VARCHAR2(30), CSID=852): '4000874'

Predicate Information (identified by operation id):

---------------------------------------------------

4 - filter(("RATABLE_RESOURCE_ID"=TO_NUMBER(:V1) OR "TRANSFER_RESOURCE_ID"=TO_NUMBER(:V2)))

我說沒錯,确實是有隐式類型轉換。但是,這個隐式類型轉換卻是“無害”的,因為如果字段是number類型,綁定變量是varchar2類型,這種隐式類型轉換是不會影響SQL執行計劃的。而如果字段是varchar2類型,綁定變量是number類型,這種才是最危險的。

小陳接下來發了完整的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的差別,還是會比較迷惑。而且客戶之前被隐式類型轉換折騰過幾次,這次發現一個,可惜卻不是根因。