索引是影響資料庫效能的關鍵物件。雖然文獻眾多,實務上仍存許多誤解。本文針對三大常見議題,以 Oracle 8.1.7 實測數據深度剖析。
優化器若選擇全表掃描而非索引掃描,通常因兩大原因:
成本估算公式約為:FF * (CF + 索引區塊數)。讀取區塊越多,Cost 越大,越傾向全表掃描。
表 mytables 32 萬筆,主鍵 myid 範圍 1~409654。
SELECT * FROM mytables WHERE myid >= 1 → FF=100% → 全表掃描,Cost=3132,讀 41473 區塊SELECT * FROM mytables WHERE myid >= 400000 → FF≈1% → 索引範圍掃描,Cost=346,讀 6647 區塊FF 差異導致截然不同的執行計畫。撰寫 SQL 前預估 FF 可預判索引是否會被使用。
常見誤區:
查詢欄位全包含於複合索引時,Oracle 僅掃描索引即可取得所有資料,稱為 Index Only Access Path,極快。
SELECT COUNT(1) FROM mytabs
WHERE coid >= 130000 AND issuedate >= TO_DATE('2001-07-20','yyyy-mm-dd');
I_mytabs1(coid), I_mytabs2(issuedate):讀 7000 區塊,Cost=384I_mytabs_test(coid, issuedate):讀 300 區塊,Cost=37000 vs 300 區塊,複合索引效能碾壓。索引設計需結合應用整體分析。
Oracle 使用索引的基本條件:
-- 錯誤:欄位參與函數運算
WHERE TO_DATE(updatedate) >= TO_DATE('2001-7-18','YYYY-MM-DD')
-- 顯式阻止索引的操作符
f1 > f2, f1 IS NULL, f1 IS NOT NULL, f1 NOT IN, f1 !=, f1 LIKE '%pattern%', NOT EXISTS
-- 某些情況下 IN 也會失效
IN 可嘗試改寫為 比較運算 + UNION ALLEXPLAIN PLAN 驗證執行計畫