程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> Oracle數據庫 >> Oracle數據庫基礎 >> Oracle索引使用規則簡介

Oracle索引使用規則簡介

編輯:Oracle數據庫基礎

Oracle索引相信大家都比較熟悉了,下面就為您介紹Oracle索引的使用規則,供您參考,希望可以讓您對Oracle索引有更深的認識。

首先,我們要確定數據庫運行在何種優化模式下,相應的參數是:optimizer_mode。可在svrmgrl中運行“show parameter optimizer_mode"來查看。Oracle V7以來缺省的設置應是"choose",即如果對已分析的表查詢的話選擇CBO,否則選擇RBO。如果該參數設為“rule”,則不論表是否分析過,一概選用RBO,除非在語句中用hint強制。

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

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

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

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

第六,Oracle索引列是否函數的參數。如是,索引在查詢時用不上。

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

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

第九,Oracle索引列的選擇性不高。

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

但我們考慮另一種情況,如果一百萬數據行實際不是在4種deptno值間平均分配,其中有99萬行對應著值10,5000行對應值20,3000行對應值30,2000行對應值40。在這種數據分布圖案中對除值為10外的其它deptno值搜索時,毫無疑問,如果索引能被應用,那麼效率會高出很多。我們可以采用對該索引列進行單獨分析,或用analyze語句對該列建立直方圖,對該列搜集足夠的統計數據,使Oracle在搜索選擇性較高的值能用上索引。

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

第十一,看是否有用到並行查詢(PQO)。並行查詢將不會用到索引。

第十二,看PL/SQL語句中是否有用到bind變量。由於數據庫不知道bind變量具體是什麼值,在做非相等連接時,如“<”,“>”,“like”等。Oracle將引用缺省值,在某些情況下會對執行計劃造成影響

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved