索引失效的幾個原因


1 使用不等於操作符(<>、!=
下面的查詢即使在 cust_rating 列有一個索引,查詢語句仍然執行一次全表掃描。
select cust_Id,cust_name from customers where   cust_rating <> 'aa';        
把上面的語句改成如下的查詢語句,這樣,在採用基於規則的優化器而不是基於代價的
優化器(更智能)時,將會使用索引。
select cust_Id,cust_name from customers where cust_rating < 'aa' or cust_rating > 'aa'
特別注意:通過把不等於操作符改成 OR 條件,就可以使用索引,以避免全表掃描。
2  使用 IS NULL  或 IS NOT NULL
使用 IS NULL  或 IS NOT NULL 同樣會限制索引的使用。因爲 NULL 值並沒有被定義。
在 SQL 語句中使用 NULL 會有很多的麻煩。因此建議開發人員在建表時,把需要索引的列
設成  NOT NULL。如果被索引的列在某些行中存在 NULL 值,就不會使用這個索引(除非
索引是一個位圖索引,關於位圖索引在稍後在詳細討論)。
3  使用函數
如果不使用基於函數的索引,那麼在 SQL 語句的 WHERE 子句中對存在索引的列使用
函數時,會使優化器忽略掉這些索引。  下面的查詢不會使用索引(只要它不是基於函數的
索引)
select empno,ename,deptno from emp   where   trunc(hiredate)='01-MAY -81';
把上面的語句改成下面的語句,這樣就可以通過索引進行查找。
select empno,ename,deptno from emp where   hiredate<(to_date('01-MAY -81')+0.9999);
4  比較不匹配的數據類型
也是比較難於發現的性能問題之一。  注意下面查詢的例子,account_number 是一個
VARCHAR2 類型,在 account_number 字段上有索引。
下面的語句將執行全表掃描:
select bank_name,address,city,state,zip from banks where account_number = 990354;
Oracle 可以自動把 where 子句變成 to_number(account_number)=990354,這樣就限
制了索引的使用,改成下面的查詢就可以使用索引:
select bank_name,address,city,state,zip from banks where account_number ='990354';
特別注意: 不匹配的數據類型之間比較會讓 Oracle 自動限制索引的使用,即便對這個查
詢執行 Explain Plan 也不能讓您明白爲什麼做了一次―全表掃描‖。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章