首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> Oracle 資料庫 >> Oracle 教學

Oracle 效能優化技巧:函數索引解決 WHERE 子句函數導致全表掃描

     編輯:Oracle 教學

問題場景

任何對欄位施加函數運算 (如 SUBSTR, UPPER, TRUNC, TO_CHAR) 都會導致該欄位上的一般 B-tree 索引失效,迫使優化器選擇全表掃描。

CREATE INDEX emp_ename_substr_idx 
ON emp (SUBSTR(ename, 1, 2));

驗證執行計畫

CREATE [UNIQUE | BITMAP] INDEX index_name
ON table_name (function_expression [, function_expression ...])
[TABLESPACE tablespace_name]
[COMPRESS [ADVANCED | LOW | HIGH]]
[PARALLEL degree]
[NOLOGGING];

支援的函數類型

  • 內建 SQL 函數:UPPER, LOWER, SUBSTR, TRUNC, ROUND, TO_CHAR, TO_DATE, NVL, DECODE, CASE 等
  • 使用者自訂函數 (UDF):**必須宣告為 DETERMINISTIC**
CREATE INDEX emp_ename_upper_idx ON emp (UPPER(ename));
-- 查詢
SELECT * FROM emp WHERE UPPER(ename) = 'SMITH';

2. 日期欄位範圍查詢 (避免 TRUNC)

CREATE INDEX emp_name_job_idx 
ON emp (UPPER(ename), UPPER(job));

-- 可支援查詢
WHERE UPPER(ename) = 'SMITH' AND UPPER(job) = 'CLERK';
WHERE UPPER(ename) = 'SMITH';  -- 前導欄位匹配可用

限制與注意事項

限制說明對策
查詢條件需精確匹配WHERE 子句函數運算式須與索引定義完全一致建立程式碼規範,統一函數寫法
UDF 必須 DETERMINISTIC非確定性函數無法建立索引確保函數無副作用、相同輸入必得相同輸出
增加 DML 開銷INSERT/UPDATE 需額外計算函數值維護索引評估讀寫比,高寫入表慎用
統計資訊需同步函數索引也需收集統計資訊DBMS_STATS.GATHER_TABLE_STATS(cascade=>TRUE)
不支援 BITMAP 函數索引僅 B-tree 支援低基數欄位考慮虛擬欄位 + 一般索引

替代方案:虛擬欄位 (11g+)

虛擬欄位不佔用儲存空間,可建立一般索引,語意更清晰。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved