天天看點

不該建索引及不走索引的原因

1.5 不應該建索引列的特點: 

第一,對于那些在查詢中很少使用或者參考的列不應該建立索引。這是因為,既然這些列很少使用到,是以有索引或者無索引,并不能提高查詢速度。相反,由于增加了索引,反而降低了系統的維護速度和增大了空間需求。 

第二,對于那些隻有很少資料值的列也不應該增加索引。這是因為,由于這些列的取值很少,例如人事表的性别列,在查詢的結果中,結果集的資料行占了表中資料行的很大比例,即需要在表中搜尋的資料行的比例很大。增加索引,并不能明顯加快檢索速度。 

第三,對于那些定義為blob資料類型的列不應該增加索引。這是因為,這些列的資料量要麼相當大,要麼取值很少。 

第四,當修改性能遠遠大于檢索性能時,不應該建立索引。這是因為,修改性能和檢索性能是互相沖突的。當增加索引時,會提高檢索性能,但是會降低修改性能。當減少索引時,會提高修改性能,降低檢索性能。是以,當修改性能遠遠大于檢索性能時,不應該建立索引。 

1.6 限制索引 

限制索引是一些沒有經驗的開發人員經常犯的錯誤之一。在SQL中有很多陷阱會使一些索引無法使用。下面讨論一些常見的問題: 

   1.6.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條件,就可以使用索引,以避免全表掃描。 

   1.6.2 使用IS NULL 或IS NOT NULL 

   使用IS NULL 或IS NOT NULL同樣會限制索引的使用。因為NULL值并沒有被定義。在SQL語句中使用NULL會有很多的麻煩。是以建議開發人員在建表時,把需要索引的列設成 NOT NULL。如果被索引的列在某些行中存在NULL值,就不會使用這個索引(除非索引是一個位圖索引,關于位圖索引在稍後在詳細讨論)。 

   1.6.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); 

  1.6.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也不能讓您明白為什麼做了一次“全表掃描”。 

本文轉自 張沖andy 部落格園部落格,原文連結: http://www.cnblogs.com/andy6/p/5764877.html  ,如需轉載請自行聯系原作者