oracle爲什麼不使用索引

1、檢查被索引的列或組合索引的首列是否出現在PL/SQL語句的WHERE子句中,這是“執行計劃”能用到相關索引的必要條件。

2、看採用了哪種類型的連接方式。ORACLE的共有Sort Merge Join(SMJ)、Hash Join(HJ)和Nested Loop Join(NL)。在兩張表連接,且內表的目標列上建有索引時,只有Nested Loop纔能有效地利用到該索引。SMJ即使相關列上建有索引,最多隻能因索引的存在,避免數據排序過程。HJ由於須做HASH運算,索引的存在對數據查詢速度幾乎沒有影響。

3、看連接順序是否允許使用相關索引。假設表emp的deptno列上有索引,表dept的列deptno上無索引,WHERE語句有emp.deptno=dept.deptno條件。在做NL連接時,emp做爲外表,先被訪問,由於連接機制原因,外表的數據訪問方式是全表掃描,emp.deptno上的索引顯然是用不上,最多在其上做索引全掃描或索引快速全掃描。

4、是否用到系統數據字典表或視圖。由於系統數據字典表都未被分析過,可能導致極差的“執行計劃”。但是不要擅自對數據字典表做分析,否則可能導致死鎖,或系統性能下降。

5、索引列是否函數的參數。如是,索引在查詢時用不上。

6、是否存在潛在的數據類型轉換。如將字符型數據與數值型數據比較,ORACLE會自動將字符型用to_number()函數進行轉換,從而導致上一種現象的發生。

7、是否爲表和相關的索引蒐集足夠的統計數據。對數據經常有增、刪、改的表最好定期對錶和索引進行分析,可用SQL語句“analyze table xxxx compute statistics for all indexes;”。ORACLE掌握了充分反映實際的統計數據,纔有可能做出正確的選擇。

8、索引列的選擇性不高。

  我們假設典型情況,有表emp,共有一百萬行數據,但其中的emp.deptno列,數據只有4種不同的值,如10、20、30、40。雖然emp數據行有很多,ORACLE缺省認定表中列的值是在所有數據行均勻分佈的,也就是說每種deptno值各有25萬數據行與之對應。假設SQL搜索條件DEPTNO=10,利用deptno列上的索引進行數據搜索效率,往往不比全表掃描的高。

9、索引列值是否可爲空(NULL)。如果索引列值可以是空值,在SQL語句中那些要返回NULL值的操作,將不會用到索引,如COUNT(*),而是用全表掃描。這是因爲索引中存儲值不能爲全空。

10、看是否有用到並行查詢(PQO)。並行查詢將不會用到索引。

11、如果從以上幾個方面都查不出原因的話,我們只好用採用在語句中加hint的方式強制ORACLE使用最優的“執行計劃”。

  hint採用註釋的方式,有行註釋和段註釋兩種方式。

  如我們想要用到A表的IND_COL1索引的話,可採用以下方式:

  “SELECT /*+ INDEX(A IND_COL1)*/ * FROM A WHERE COL1 = XXX;"

12. 驅動表上的索引, 如果建在選擇字段上, 是有用的, 如果建在連接字段上, 就沒有用
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章