Oracle 索引的目標是避免全表掃描,提升查詢效率,但有些時候卻拔苗助長。數據庫
例如一張表中有上百萬條數據,對某個字段加了索引,可是查詢時性能並無什麼提升,這多是 oracle 索引失效形成的。oracle 索引有一些限制條件,若是你違反了這些索引限制條件,那麼即便你已經加了索引,oracle仍是會執行一次全表掃描,查詢的性能不會比不加索引有所提升,反而可能因爲數據庫維護索引的系統開銷形成性能更差。 下面就是總結的能使 Oracle 索引失效的七大限制條件。oracle
1. 沒有 WHERE 子句ide
2. 使用 IS NULL 和 IS NOT NULL函數
SELECT ... FROM emp WHERE comm IS NULL; comm 列的索引會失效性能
3. WHERE 子句中使用函數優化
若是沒有使用基於函數的索引,那麼 where 子句中對存在索引的列使用函數時,會使優化器忽略掉這些索引。例如:spa
select * from staff where trunc(birthdate) = '01-MAY-82';orm
可是把函數應用在條件上,索引是能夠生效的,把上面的語句改爲下面的語句,就能夠經過索引進行查找。索引
select * from staff where birthdate < (to_date('01-MAY-82') + 0.9999);it
注意:對於 MIN, MAX 函數,Oracle 仍然使用索引。
4. 使用 LIKE ‘%T’ 進行模糊查詢
5. WHERE 子句中使用不等於操做
不等於操做包括:<>, !=, NOT colum >= ?, NOT colum <= ?
對於這個限制條件能夠經過 OR 替代,例如: colum <> 0 ===> colum>0 OR colum<0
6. 等於和範圍索引不會被合併使用
SELECT emp_id, emp_m, salary_q ... FROM emp WHERE job='manager' AND deptno>10
job 和 deptno 都是非惟一索引,這種條件下 oracle 不會合並索引,它只會使用第一個索引。
7. 比較不匹配數據類型
dept_id是一個varchar2型的字段,在這個字段上有索引,可是下面的語句會執行全表掃描。
select * from dept where dept_id = 900198;
這是由於 oracle 會自動把 where 子句轉換成 to_number(dept_id)=900198,至關於使用函數,這樣就限制了索引的使用。正確寫法以下:
select * from dept where dept_id = '900198';