| 類型 | 適用場景 | 基數要求 | DML 影響 | 鎖行為 |
|---|---|---|---|---|
| B-tree (預設) | 高基數、範圍查詢、JOIN、排序 | 高 (>1%) | 中 | 行級鎖 |
| Bitmap | 低基數、多條件 AND/OR、DW/OLAP | 低 (<1%) | 大 (鎖定整個 bitmap 片段) | 不支援行級鎖 |
| Function-based | 函數/運算式查詢 (UPPER, SUBSTR, 算術) | 視函數結果 | 中 | 行級鎖 |
| Domain | 空間、文字、多媒體等擴展型別 | 特定 | 特定 | 特定 |
性別 (M/F)、婚姻狀態 (S/M/D/W)、部門代碼 (<50 個值)
CREATE BITMAP INDEX idx_emp_gender ON emp(gender);
CREATE BITMAP INDEX idx_emp_dept ON emp(deptno);
Oracle 可直接對 Bitmap 做位元運算,極快:
SELECT * FROM emp
WHERE gender = 'F' AND deptno = 10 AND status = 'ACTIVE';
三個 Bitmap 索引位元 AND 運算,無需回表即可定位 ROWID。
B-tree 不索引全 NULL 鍵值,Bitmap 索引包含 NULL:
CREATE BITMAP INDEX idx_emp_id_null ON emp(id_card);
SELECT * FROM emp WHERE id_card IS NULL; -- 走 Bitmap 索引
CREATE INDEX idx_emp_cover ON emp(deptno, empno, ename, sal);
SELECT ename, sal FROM emp WHERE deptno = 10; -- Index Only Scan
-- 大小寫不敏感查詢
CREATE INDEX idx_emp_upper_name ON emp(UPPER(ename));
SELECT * FROM emp WHERE UPPER(ename) = 'SMITH';
-- 日期運算
CREATE INDEX idx_orders_year ON orders(EXTRACT(YEAR FROM order_date));
SELECT * FROM orders WHERE EXTRACT(YEAR FROM order_date) = 2023;
-- 算術運算
CREATE INDEX idx_sal_bonus ON emp(sal + NVL(comm,0));
SELECT * FROM emp WHERE (sal + NVL(comm,0)) > 5000;
需設定 QUERY_REWRITE_ENABLED=TRUE、QUERY_REWRITE_INTEGRITY=TRUSTED。
ANALYZE INDEX ... VALIDATE STRUCTURE 檢查碎片ALTER INDEX ... REBUILD ONLINEV$OBJECT_USAGE (11g+) 識別未使用索引並移除DBMS_STATS.GATHER_TABLE_STATS(..., METHOD_OPT=>'FOR ALL INDEXED COLUMNS')