Oracle 在比較不同資料類型的欄位與常數時,會自動進行隱式轉換。若轉換發生在索引欄位上,會導致索引無法使用,造成全表掃描,嚴重拖慢查詢效能。
表 tab1 的 col1 為 CHAR/VARCHAR2 類型,查詢寫成:
SELECT col1, col2 FROM tab1 WHERE col1 > 10;
Oracle 會隱式執行 TO_NUMBER(col1) > 10,導致 col1 索引失效,執行計畫出現 TABLE ACCESS FULL。
SELECT col1, col2 FROM tab1 WHERE col1 > '10';
常數加上單引號,型別與欄位一致,優化器可直接使用 col1 索引進行 INDEX RANGE SCAN。
| 情境 | 錯誤寫法 | 正確寫法 |
|---|---|---|
| 數字欄位比字串 | WHERE num_col = '100' | WHERE num_col = 100 |
| 日期欄位比字串 | WHERE dt_col = '2024-01-01' | WHERE dt_col = DATE '2024-01-01' 或 TO_DATE(...) |
| 隱式轉換在運算式中 | WHERE col1 || '' = 'abc' | WHERE col1 = 'abc' |
EXPLAIN PLAN / DBMS_XPLAN:觀察 FILTER 或 INTERNAL_FUNCTION 關鍵字。V$SQL_PLAN:查看 ACCESS_PREDICATES 與 FILTER_PREDICATES 差異。CURSOR_SHARING=FORCE 觀察是否產生 SYS_NC... 虛擬欄位。PreparedStatement 繫結變數,由驅動程式自動處理型別對應。CAST、TO_CHAR、TO_NUMBER、TO_DATE 等轉換函數,避免依賴隱式轉換。