函數索引 (Function-Based Index) 能針對 `WHERE UPPER(name) = 'SMITH'` 這類查詢生效,但有一個嚴格限制:**查詢條件必須與索引定義的表達式完全等值匹配**,否則優化器會忽略索引退回全表掃描。
-- 建立函數索引
CREATE INDEX idx_emp_name_substr ON emp(SUBSTR(ename,1,1));
-- 查詢:首字母為 'S'
SELECT * FROM emp WHERE SUBSTR(ename,1,1) = 'S'; -- ✅ 使用索引
-- 查詢:首字母不為 'S' (範圍/不等值)
SELECT * FROM emp WHERE SUBSTR(ename,1,1) <> 'S'; -- ❌ 全表掃描
SELECT * FROM emp WHERE SUBSTR(ename,1,1) > 'S'; -- ❌ 全表掃描
SUBSTR(ename,1,1)SUBSTR(ename,1,1) = 常數 或 SUBSTR(ename,1,1) = 變數 (Bind Variable)。<>, >, LIKE) 都會導致失效。傳統 B-Tree 索引一旦建立,所有針對該欄位的查詢可能受影響 (計劃變更)。函數索引只有「精確使用該函數表達式」的查詢才會被考慮,降低對現有應用的副作用,適合針對性優化特定問題 SQL。
DBMS_STATS.GATHER_TABLE_STATS(..., METHOD_OPT=>'FOR ALL HIDDEN COLUMNS') 收集虛擬欄位統計。INDEX RANGE SCAN (或 INDEX UNIQUE SCAN)。