任何對欄位的運算(函數、表達式、類型轉換)都會導致該欄位索引失效,迫使全表掃描。
原因:運算結果需在執行時逐行計算,優化器無法在編譯期利用索引預估選擇性。
| 原始 SQL (30 萬行,耗時 10-13 秒) | 問題 |
|---|---|
WHERE SUBSTRB(CardNo,1,4) = '5378' | 函數運算 |
WHERE amount/30 < 1000 | 算術運算 |
WHERE TO_CHAR(ActionTime,'yyyymmdd') = '19991201' | 轉換函數 |
| 優化後 SQL | 技巧 |
|---|---|
WHERE CardNo LIKE '5378%' | 前綴匹配可用索引 |
WHERE amount < 1000*30 | 常數折疊移至右側 |
WHERE ActionTime = TO_DATE('19991201','yyyymmdd') | 常數轉換而非欄位轉換 |
NVL(col,0)、COALESCE(col,0) → 改用 col IS NULL OR col = 0 或函數索引TRUNC(date_col) → 改用 date_col >= TRUNC(SYSDATE) AND date_col < TRUNC(SYSDATE)+1WHERE num_col = '123' → 明確 TO_NUMBER 或修正應用層參數綁定類型CREATE INDEX idx_fbi ON t(UPPER(name));EXPLAIN PLAN FOR; SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY); -- 觀察 Operation 是否為 INDEX RANGE SCAN vs TABLE ACCESS FULL