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

數據庫索引設計全攻略:優缺點權衡、適用場景判斷與創建策略最佳實踐

     編輯:Oracle 教學

為什麼需要索引? — 五大核心收益

  1. 強制唯一性:唯一索引/主鍵約束保證業務鍵不重複。
  2. 加速檢索:B-Tree 邏輯導航將 O(N) 全表掃描降為 O(log N) 索引掃描,**最核心動機**。
  3. 加速連接:外鍵列索引使 Nested Loops / Hash Join 構建 Probe 端極快,支撐參考完整性高效檢查。
  4. 優化排序/分組:索引天然有序,ORDER BY/GROUP BY 列有索引可避免 Sort 操作。
  5. 輔助優化器決策:索引統計信息 (NDV、直方圖、聚簇因子) 讓 CBO 更精準估算選擇性。

為什麼不給每列加索引? — 三大代價

  1. 維護時間隨數據量線性增長:每次 INSERT/DELETE/UPDATE 索引列,所有相關索引同步修改 (B-Tree 分裂/合并、位圖鎖)。
  2. 佔用物理空間:索引段獨立佔用表空間,聚簇索引 (IOT) 更是數據與索引融合,空間放大明顯。
  3. 拖慢 DML 性能:寫入路徑變長、Redo/Undo 量增大、並發鎖競爭 (特別是位圖索引、反向鍵索引)。

應該在哪些列創建索引? — 六大標準場景

場景典型列索引類型建議
高頻 WHERE 條件列訂單號、用戶 ID、手機號、身份證B-Tree (高基數) / 位圖 (低基數、數倉)
主鍵列PK 定義列唯一 B-Tree (主鍵約束自動創建)
外鍵/關聯列FK 列、JOIN ON 列B-Tree (加速 NLJ/HJ 構建)
範圍查詢列創建時間、交易金額、日期B-Tree (有序特性天然支持範圍)
排序/分組列ORDER BY col, GROUP BY colB-Tree (避免 SORT ORDER BY)
覆蓋索引候選SELECT 列集合較小、高頻複合索引包含所有 SELECT 列 (Index Only Scan)

不應該創建索引的列 — 四大反模式

  1. 極少查詢引用:維護成本 > 查詢收益。
  2. 極低基數 (選擇性極差):性別、狀態碼 (0/1)、是否刪除旗標。全表掃描更快,優化器通常會忽略此類索引。
  3. LOB/超長文本/二進制列:CLOB/BLOB/LONG/RAW — 數據量大、不可直接索引 (需 Context/全文索引)。
  4. 高頻 DML、低頻查詢的表:日志表、臨時表、階段表 — 寫入性能優先,索引為負資產。

索引創建兩大路徑

路徑語法/方式特點適用場景
直接創建CREATE [UNIQUE|BITMAP] INDEX idx_name ON tbl(col1, col2) [TABLESPACE ts] [COMPRESS n] [ONLINE] [PARALLEL n];最靈活:可指定類型、唯一性、複合列順序、壓縮、在線構建、並行度精細調優、覆蓋索引、函數索引、域索引
約束間接創建ALTER TABLE tbl ADD CONSTRAINT pk_name PRIMARY KEY (col) USING INDEX (CREATE INDEX ...);
ALTER TABLE tbl ADD CONSTRAINT uk_name UNIQUE (col);
PK → 唯一聚簇索引 (IOT) 或唯一非聚簇;UK → 唯一非聚簇。類型固定,定制度低。標準化建模、主鍵/唯一約束同步建立

優先級:約束創建的索引 **覆蓋** 同列同序的標準索引 (約束索引優先級更高)。

索引兩大核心特征

1. 唯一性索引

  • 保證索引鍵值全表唯一 (含 NULL 行視為唯一,Oracle 允許多 NULL)
  • 創建時檢查現有數據,DML 時實時檢查,違反即報錯回滾
  • **業務主鍵/唯一鍵必走約束**,而非單獨創建唯一索引 (約束語義更清晰、工具支持更好)

2. 複合索引 (多列索引)

  • 最多 32 列 (12c+),總長度 ≤ 75% 塊大小 (~6KB)
  • **列順序決定一切**:最左前綴原則 — 查詢必須包含前導列才能使用索引
  • 排序規則:最高選擇性 (最唯一) 列放最前,其次是範圍/排序列,最後是覆蓋列
  • 示例:CREATE INDEX idx_order_cust_dt ON orders(cust_id, order_dt, amount); — cust_id 高選擇性在前,order_dt 範圍在中,amount 覆蓋在後
  • 優勢:一個索引服務多種查詢 (WHERE cust_id=? / WHERE cust_id=? AND order_dt>? / WHERE cust_id=? ORDER BY order_dt),減少索引總數

最佳實踐清單

  1. 建模階段即規劃索引:PK/FK/高頻查詢列同步設計,避免上線後補救。
  2. 命名規範:PK_表, UK_表_列, IDX_表_列1_列2, BIX_表_列 (位圖)。
  3. 定期審計:DBA_INDEXES + V$OBJECT_USAGE (MONITORING USAGE) 識別長期未用索引 → 刪除。
  4. 監控聚簇因子:CLUSTERING_FACTOR ≈ NUM_ROWS (好) vs ≈ BLOCKS (壞) → 考慮重建表/索引或調整 PCTFREE。
  5. 在線構建 (ONLINE):生產庫創建/重建大索引必加 ONLINE,避免 DML 阻塞。
  6. 壓縮前導列:COMPRESS n (n=前導重複列數) 節省空間、提升緩存命中。
  7. 不可见索引 (12c+):INVISIBLE 測試新索引影響,驗證無負面再 VISIBLE。

總結

索引是 **「查詢加速器」與「寫入負擔」的雙刃劍**。
**黃金法則**:
1. **只為高頻、高選擇性、關聯、排序列建索引**
2. **複合索引列順序 = 選擇性遞減 + 業務查詢模式覆蓋**
3. **定期用 MONITORING USAGE 清理僵尸索引**
4. **約束管理主鍵/唯一,直接創建管理業務加速索引**
將索引視為「稀缺資源」精細化管理,才能在讀寫平衡點上持續交付性能。

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