oracle 提供了cbo、rbo兩種sql優化器。cbo在oracle7 引入,但在oracle8i 中才成熟。oracle 已經明確宣告在oracle9i
之後的版本中(oracle 10g ),rbo將不再支援。因此選擇cbo 是必然的趨勢。
cbo和 rbo作為不同的sql優化器,對sql語句的執行計畫產生重大影響,如果要對現有的應用程式從rbo向cbo移植,則必須充分
考慮這些影響,避免sql語句效能急劇下降;但是,對新的應用系統,則可以考慮直接使用cbo,在cbo模式下進行sql語句編寫、分析
執行計畫、效能測試等工作,這需要開發者對cbo的特性比較熟悉。以下小結幾點在cbo下寫sql語句的注意事項:
1、rbo自oracle 6版以來被採用,有著一套嚴格的使用規則,只要你按照它去寫sql語句,無論資料表中的內容怎樣,也不會影響到你的
「執行計畫」,也就是說對資料不「敏感」;cbo計算各種可能「執行計畫」的「代價」,即cost,從中選用cost最低的方案,作為實際
執行方案。各「執行計畫」的cost的計算根據,依賴於資料表中資料的統計分布,oracle資料庫本身對該統計分布並不清楚,必須要分
析表和相關的索引(使用analyze 命令),才能蒐集到cbo所需的資料。
2、使用cbo 時,編寫sql語句時,不必考慮"from" 子句後面的表或檢視的順序和"where" 子句後面的條件順序;
oracle自7版以來採用的許多新技術都是基於cbo的,如星型連線排列查詢,雜湊連線查詢,函式索引,和並行查詢等。
3、一般而言,cbo所選擇的「執行計畫」都不會比rbo的「執行計畫」差,而且相對而言,cbo對程式設計師的要求沒有rbo那麼苛刻,節省了程
序員為了從多個可能的「執行計畫」中選擇乙個最優的方案而花費的除錯時間,但在某些場合下也會存在問題。
仔細分析執行計畫,找出原因。例如,可以看連線順序是否允許使用相關索引。假設表emp的deptno列上有索引,表dept的列deptno上無
索引,where語句有emp.deptno=dept.deptno條件。在做nl連線時,emp做為外表,先被訪問,由於連線機制原因,外表的資料訪問方式是
全表掃瞄,emp.deptno上的索引顯然是用不上,最多在其上做索引全掃瞄或索引快速全掃瞄。
4、如果乙個語句使用 rbo的執行計畫確實比cbo 好,則可以通過加 " rule" 提示,強制使用rbo。
5、使用cbo 時,sql語句 "from" 子句後面的表,必須全部使用analyze 命令分析過,如果"from" 子句後面的是檢視,則此檢視的
基礎表,也必須全部使用analyze 命令分析過;否則,oracle 會在執行此sql語句之前,自動進行analyze 命令分析,這會極大
導致sql語句執行極其緩慢。
6、使用cbo 時,sql語句 "from" 子句後面的表的個數不宜太多,因為cbo在選擇表連線順序時,會對"from" 子句後面的表進行階乘
運算,選擇最好的乙個連線順序。假如"from" 子句後有6個表,則其可選擇的連線順序就是6*5*4*3*2*1 = 720 種,cbo 選擇其中
一種,而如果"from" 子句後有12個表,則其可選擇的連線順序就是12*11*10*9*8*7*6*5*4*3*2*1= 479001600 種,可以想象從中選
擇一種,會消耗多少cpu 時間?如果實在是要訪問很多表,則最好使用 order 提示,強制使用"from" 子句表固定的訪問順序。
7、使用cbo 時,sql語句中不能引用系統資料字典表或檢視,因為系統資料字典表都未被分析過,可能導致極差的「執行計畫」。但是
不要擅自對資料字典表做分析,否則可能導致死鎖,或系統效能嚴重下降。
8、使用cbo 時,要注意看採用了哪種型別的表連線方式。oracle的共有sort merge join(smj)、hash join(hj)和nested loop join
(nl)。cbo有時會偏重於smj 和 hj,但在oltp 系統中,nl 一般會更好,因為它高效的使用了索引。
在兩張表連線,且內錶的目標列上建有索引時,只有nested loop才能有效地利用到該索引。smj即使相關列上建有索引,最多只能因索引
的存在,避免資料排序過程。hj由於須做hash運算,索引的存在對資料查詢速度幾乎沒有影響。
9、使用cbo 時,必須保證為表和相關的索引蒐集足夠的統計資料。對資料經常有增、刪、改的表最好定期對錶和索引進行分析,可用sql
語句「analyze table *** compute statistics for all indexes;"oracle掌握了充分反映實際的統計資料,才有可能做出正確的選擇。
10、使用cbo 時,要注意被索引的字段的值的資料分布,會影響sql語句的執行計畫。例如:
表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在搜
索選擇性較高的值能用上索引。
CBO,RBO在ORACLE中的應用
oracle 提供了cbo rbo兩種sql優化器。cbo在oracle7 引入,但在oracle8i 中才成熟。oracle 已經明確宣告在oracle9i之後的版本中 oracle 10g rbo將不再支援。因此選擇cbo 是必然的趨勢。cbo和 rbo作為不同的sql優化器,對sql語句的執行...
CBO,RBO在ORACLE中的應用
oracle 提供了cbo rbo兩種sql優化器。cbo在oracle7 引入,但在oracle8i 中才成熟。oracle 已經明確宣告在oracle9i之後的版本中 oracle 10g rbo將不再支援。因此選擇cbo 是必然的趨勢。cbo和 rbo作為不同的sql優化器,對sql語句的執行...
效能優化 CBO,RBO在ORACLE中的應用
oracle 提供了cbo rbo兩種sql優化器。cbo在oracle7 引入,但在oracle8i 中才成熟。oracle已經明確宣告在oracle9i之後的版本中 oracle 10g rbo將不再支援。cbo和 rbo作為不同的sql優化器,對sql語句的執行計畫產生重大影響,如果要對現有的...