首先,我們要確定數(shù)據(jù)庫(kù)運(yùn)行在何種優(yōu)化模式下,相應(yīng)的參數(shù)是:optimizer_mode??稍趕vrmgrl中運(yùn)行“show parameter optimizer_mode"來(lái)查看。ORACLE V7以來(lái)缺省的設(shè)置應(yīng)是"choose",即如果對(duì)已分析的表查詢(xún)的話選擇CBO,否則選擇RBO。如果該參數(shù)設(shè)為“rule”,則不論表是否分析過(guò),一概選用RBO,除非在語(yǔ)句中用hint強(qiáng)制。 其次,檢查被索引的列或組合索引的首列是否出現(xiàn)在PL/SQL語(yǔ)句的WHERE子句中,這是“執(zhí)行計(jì)劃”能用到相關(guān)索引的必要條件。 第三,看采用了哪種類(lèi)型的連接方式。ORACLE的共有Sort Merge Join(SMJ)、Hash Join(HJ)和Nested Loop Join(NL)。在兩張表連接,且內(nèi)表的目標(biāo)列上建有索引時(shí),只有Nested Loop才能有效地利用到該索引。SMJ即使相關(guān)列上建有索引,最多只能因索引的存在,避免數(shù)據(jù)排序過(guò)程。HJ由于須做HASH運(yùn)算,索引的存在對(duì)數(shù)據(jù)查詢(xún)速度幾乎沒(méi)有影響。 第四,看連接順序是否允許使用相關(guān)索引。假設(shè)表emp的deptno列上有索引,表dept的列deptno上無(wú)索引,WHERE語(yǔ)句有emp.deptno=dept.deptno條件。在做NL連接時(shí),emp做為外表,先被訪問(wèn),由于連接機(jī)制原因,外表的數(shù)據(jù)訪問(wèn)方式是全表掃描,emp.deptno上的索引顯然是用不上,最多在其上做索引全掃描或索引快速全掃描。 第五,是否用到系統(tǒng)數(shù)據(jù)字典表或視圖。由于系統(tǒng)數(shù)據(jù)字典表都未被分析過(guò),可能導(dǎo)致極差的“執(zhí)行計(jì)劃”。但是不要擅自對(duì)數(shù)據(jù)字典表做分析,否則可能導(dǎo)致死鎖,或系統(tǒng)性能下降。
第七,是否存在潛在的數(shù)據(jù)類(lèi)型轉(zhuǎn)換。如將字符型數(shù)據(jù)與數(shù)值型數(shù)據(jù)比較,ORACLE會(huì)自動(dòng)將字符型用to_number()函數(shù)進(jìn)行轉(zhuǎn)換,從而導(dǎo)致第六種現(xiàn)象的發(fā)生。 第八,是否為表和相關(guān)的索引搜集足夠的統(tǒng)計(jì)數(shù)據(jù)。對(duì)數(shù)據(jù)經(jīng)常有增、刪、改的表最好定期對(duì)表和索引進(jìn)行分析,可用SQL語(yǔ)句“analyze table xxxx compute statistics for all indexes;"。ORACLE掌握了充分反映實(shí)際的統(tǒng)計(jì)數(shù)據(jù),才有可能做出正確的選擇。 第九,索引列的選擇性不高。 我們假設(shè)典型情況,有表emp,共有一百萬(wàn)行數(shù)據(jù),但其中的emp.deptno列,數(shù)據(jù)只有4種不同的值,如10、20、30、40。雖然emp數(shù)據(jù)行有很多,ORACLE缺省認(rèn)定表中列的值是在所有數(shù)據(jù)行均勻分布的,也就是說(shuō)每種deptno值各有25萬(wàn)數(shù)據(jù)行與之對(duì)應(yīng)。假設(shè)SQL搜索條件DEPTNO=10,利用deptno列上的索引進(jìn)行數(shù)據(jù)搜索效率,往往不比全表掃描的高,ORACLE理所當(dāng)然對(duì)索引“視而不見(jiàn)”,認(rèn)為該索引的選擇性不高。 但我們考慮另一種情況,如果一百萬(wàn)數(shù)據(jù)行實(shí)際不是在4種deptno值間平均分配,其中有99萬(wàn)行對(duì)應(yīng)著值10,5000行對(duì)應(yīng)值20,3000行對(duì)應(yīng)值30,2000行對(duì)應(yīng)值40。在這種數(shù)據(jù)分布圖案中對(duì)除值為10外的其它deptno值搜索時(shí),毫無(wú)疑問(wèn),如果索引能被應(yīng)用,那么效率會(huì)高出很多。我們可以采用對(duì)該索引列進(jìn)行單獨(dú)分析,或用analyze語(yǔ)句對(duì)該列建立直方圖,對(duì)該列搜集足夠的統(tǒng)計(jì)數(shù)據(jù),使ORACLE在搜索選擇性較高的值能用上索引。 第十,索引列值是否可為空(NULL)。如果索引列值可以是空值,在SQL語(yǔ)句中那些需要返回NULL值的操作,將不會(huì)用到索引,如COUNT(*),而是用全表掃描。這是因?yàn)樗饕写鎯?chǔ)值不能為全空。 第十一,看是否有用到并行查詢(xún)(PQO)。并行查詢(xún)將不會(huì)用到索引。 第十二,看PL/SQL語(yǔ)句中是否有用到bind變量。由于數(shù)據(jù)庫(kù)不知道bind變量具體是什么值,在做非相等連接時(shí),如“<”,“>”,“l(fā)ike”等。ORACLE將引用缺省值,在某些情況下會(huì)對(duì)執(zhí)行計(jì)劃造成影響。 |
|
來(lái)自: guolijiegg > 《oracle》