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

Oracle 索引失效七大陷阱:函數、隱式轉換、不等於、LIKE%、IS NULL、複合索引不合併、類型不匹配完整避坑指南

     編輯:Oracle 教學

Oracle 索引失效七大陷阱:完整避坑指南與改寫範例

實戰案例:分頁查詢 20 筆耗時 16 秒,執行計畫顯示全表掃描。優化後改用索引範圍掃描,耗時降至毫秒級。根因在 WHERE 條件對索引欄使用函數導致索引失效。

七大失效陷阱與改寫

#陷阱失效範例改寫方案
1WHERE 條件對索引欄使用函數WHERE TRUNC(birthdate) = '01-MAY-82'建立函數索引 CREATE INDEX ... ON t(TRUNC(birthdate));或改寫 WHERE birthdate >= DATE '1982-05-01' AND birthdate < DATE '1982-05-02'
2隱式資料類型轉換WHERE dept_id = 900198 (dept_id 為 VARCHAR2)常數加引號 WHERE dept_id = '900198';應用端使用繫結變數
3不等於操作 (<>, !=, NOT >=, NOT <=)WHERE status <> 0改用 WHERE status > 0 OR status < 0 (配合索引);或接受全掃
4LIKE '%abc' 開頭萬用字元WHERE name LIKE '%son'若固定後綴,建立反轉函數索引 REVERSE(name);否則全掃
5IS NULL / IS NOT NULLWHERE comm IS NULL單欄索引不存全 NULL;組合索引非全 NULL 會被索引;考慮 NVL(comm,-1) 函數索引
6複合索引不合併 (等值+範圍)WHERE job='MGR' AND deptno>10 (兩非唯一索引)建立組合索引 (job, deptno);或接受單一索引存取
7無 WHERE 條件SELECT * FROM big_table加上過濾條件;或使用分頁/抽樣

實戰優化前後對比

優化前 (全表掃描)

WHERE TO_NUMBER(TO_CHAR(TO_DATE(tran_date,'yyyy-mm-dd hh24:mi:ss'),'YYYYMMDD')) >= ...
-- 執行計畫: TABLE ACCESS FULL, Cost 188776

優化後 (索引範圍掃描)

WHERE tran_date >= ? AND tran_date <= ? AND clear_date >= ? AND clear_date <= ?
-- 執行計畫: INDEX RANGE SCAN DESCENDING, Cost 8

進階:為何 CLEAR_DATE 索引未被合併使用?

Oracle 對非唯一索引不支援 Index Merge (Bitmap AND/OR 僅限位圖索引)。建立組合索引 (tran_date, clear_date) 可同時服務兩欄條件。

檢測索引使用狀況

SELECT index_name, index_type, uniqueness, status
FROM user_indexes WHERE table_name = 'TRADEWASTE';

EXPLAIN PLAN FOR SELECT ...;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);

最佳實務

  1. 開發階段以 EXPLAIN PLAN 驗證所有核心 SQL 走索引。
  2. 定期收集統計資訊 (DBMS_STATS.GATHER_TABLE_STATS) 確保優化器決策準確。
  3. 針對高頻查詢建立覆蓋索引 (包含 SELECT 清單所有欄位) 實現 Index Only Scan。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved