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

Oracle 索引失效全景圖譜:14 大核心原因、隱式轉換陷阱與 CBO 成本決策深度解析

     編輯:Oracle 教學

現象定義

「索引失效」實為:**優化器選擇全表掃描而非索引訪問**,或**索引存在但無法被正確使用**。分為「結構性失效」(索引不可用)與「選擇性失效」(CBO 判斷不划算)。

14 大核心失效原因分類圖譜

I. SQL 編寫層面(開發者可控)

#原因錯誤示例正確示例原理
1隱式類型轉換WHERE varchar_col = 123WHERE varchar_col = '123'數字轉字符導致列函數化,索引無法匹配
2列上操作/函數WHERE id - 1 = 9
WHERE ROUND(id) = 10
WHERE id = 10
CREATE INDEX fbi ON t(ROUND(id))
破壞索引列順序/值,需建函數索引 (FBI)
3LIKE 通配符前置WHERE name LIKE '%abc'WHERE name LIKE 'abc%'B-Tree 索引需前綴匹配,前置 % 導致全掃描
4復合索引非前導列單獨引用索引 (a,b,c),查詢 WHERE b=1WHERE a=1 AND b=2 或建單列索引索引樹按 (a,b,c) 排序,缺前導列無法定位
5字符列存數字未加引號同 #1,極高頻錯誤同上同 #1
6NOT IN / NOT EXISTSWHERE id NOT IN (SELECT ...)WHERE NOT EXISTS (SELECT 1 ...) 或 LEFT JOIN ... WHERE IS NULLNULL 語義導致優化器放棄索引半連接
7日期/時間類型不匹配變量 TIMESTAMP vs 列 DATE統一類型或顯式 CAST隱式轉換導致列函數化

II. 數據與統計層面(DBA 可控)

#原因表現對策
8統計信息缺失/過期CBO 誤估基數,選錯計劃DBMS_STATS.GATHER_TABLE_STATS 定時任務,增量統計
9數據傾斜無直方圖熱門值走全掃,冷門值走索引METHOD_OPT=>'FOR COLUMNS SIZE AUTO/SKEWONLY col'
10表太小/選擇率過高返回行數 > 表行數 10%~15%全表掃描確實更快,接受或建議分區/叢集
11索引本身損壞/標記 UNUSABLESTATUS='UNUSABLE'ALTER INDEX ... REBUILD / REBUILD ONLINE

III. 特殊索引類型行為差異

索引類型IS NULLIS NOT NULL備註
B-Tree❌ 不存 NULL(單列)✅ 走索引復合索引全 NULL 不存,部分 NULL 存
Bitmap✅ 存 NULL✅ 走索引低基數列首選,OLAP 環境

IV. 復合索引 IS NULL/IS NOT NULL 精細規則

  • 索引 (a,b,c):
  • WHERE a IS NULL → ❌ 不走(單列 NULL 不入 B-Tree)。
  • WHERE a=1 AND b IS NULL → ✅ 走(前導列有值,後續列 NULL 存入索引)。
  • WHERE a IS NULL AND b IS NULL → ❌ 不走(前導列 NULL)。
  • WHERE a=1 AND b=2 AND c IS NULL → ✅ 走。

CBO 成本決策視角:為什麼「明明有索引」卻全表掃描?

CBO 計算公式簡化:

Index Cost ≈ BLEVEL + CEIL(Leaf_Blocks * Selectivity) + CEIL(Clustering_Factor * Selectivity)
FTS Cost   ≈ Blocks / MBRC * MREADTIM / SREADTIM
  • Clustering Factor (CF) 接近 Blocks:數據順序與索引順序一致,索引極優。
  • CF 接近 Num_Rows:數據亂序,索引回表隨機 I/O 嚴重,CBO 傾向 FTS。
  • MBRC (多塊讀計數) 大:FTS 成本進一步降低。

**結論**:索引不僅要「存在」,更要「有序」(低 CF)。大量隨機插入的表需定期 ALTER INDEX REBUILD 或採用 INDEX ORGANIZED TABLE。

診斷工具鏈

  1. EXPLAIN PLAN / DBMS_XPLAN.DISPLAY_CURSOR:確認訪問路徑。
  2. 10053 Trace:查看 CBO 內部成本計算細節。
  3. DBMS_STATS.REPORT_COL_USAGE:檢查列使用情況,指導統計收集。
  4. V$OBJECT_USAGE:監控索引實際使用情況(ALTER INDEX ... MONITORING USAGE)。

一句話總結

索引失效多源於隱式轉換、列運算、統計失真、高選擇率、Clustering Factor 差;診斷看計劃、補統計、建 FBI、重構索引、調優 CF。

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