**:http://tech.it168.com/db/o/2006-08-09/200608091935599.shtml it168技術開發
http://xu20cn.blog.51cto.com/274020/90329 信念——51cto技術部落格
oracle的優化器有兩種優化方式,即基於規則的優化方式(rule-based optimization,簡稱為rbo)和基於代價的優化方式(cost-based optimization,簡稱為cbo),在oracle8及以後的版本,oracle強列推薦用cbo的方式
rbo方式:優化器在分析sql語句時,所遵循的是oracle內部預定的一些規則。比如我們常見的,當乙個where子句中的一列有索引時去走索引。
cbo方式:它是看語句的代價(cost),這裡的代價主要指cpu和記憶體。優化器在判斷是否用這種方 式時,主要參照的是表及索引的統計資訊。統計資訊給出表的大小、有少行、每行的長度等資訊。這些統計資訊起初在庫內是沒有的,是做analyze後才出現 的,很多的時侯過期統計資訊會令優化器做出乙個錯誤的執行計畫,因些應及時更新這些資訊。
注意:走索引不一定就是優的,比如乙個表只有兩行資料,一次io就可以完成全表的檢索,而此時走索引時則需要兩次io,這時全表掃瞄(full table scan)是最好
優化模式包括rule、choose、first rows、all rows四種方式:
rule:基於規則的方式。
choolse:預設的情況下oracle用的便是這種方式。指的是當乙個表或或索引有統計資訊,則走cbo的方式,如果表或索引沒統計資訊,表又不是特別的小,而且相應的列有索引時,那麼就走索引,走rbo的方式。
first rows:它與choose方式是類似的,所不同的是當乙個表有統計資訊時,它將是以最快的方式返回查詢的最先的幾行,從總體上減少了響應時間。
all rows:也就是我們所說的cost的方式,當乙個表有統計資訊時,它將以最快的方式返回表的所有的行,從總體上提高查詢的吞吐量。沒有統計資訊則走rbo的方式。
設定選用哪種優化模式:
a、instance級別我們可以通過在initsid.ora檔案中設定optimizer_mode=rule/choose/first_rows/all_rows如果沒設定optimizer_mode引數則預設用的是choose方式。
b、sessions級別通過alter session set optimizer_mode=rule/choose/first_rows/all_rows來設定。
c、語句級別用hint(/*+ ... */)來設定
為什麼表的某個字段明明有索引,但執行計畫卻不走索引?
1、優化模式是all_rows的方式
2、表作過analyze,有統計資訊
3、表很小,上文提到過的,oracle的優化器認為不值得走索引。
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在搜尋選擇性較高的值能用上索引。
oracle的RBO CBO優化器
oracle的優化器有兩種優化方式,即基於規則的優化方式 rule based optimization,簡稱為rbo 和基於代價的優化方式 cost based optimization,簡稱為cbo 在oracle8及以後的版本,oracle強列推薦用cbo的方式 rbo方式 優化器在分析sql...
oracle的RBO CBO優化器
oracle的優化器有兩種優化方式,即基於規則的優化方式 rule based optimization,簡稱為rbo 和基於代價的優化方式 cost based optimization,簡稱為cbo 在oracle8及以後的版本,oracle強列推薦用cbo的方式 rbo方式 優化器在分析sql...
詳介oracle的RBO CBO優化器
oracle的優化器有兩種優化方式,即基於規則的優化方式 rule based optimization,簡稱為rbo 和基於代價的優化方式 cost based optimization,簡稱為cbo 在oracle8及以後的版本,oracle強列推薦用cbo的方式 rbo方式 優化器在分析sql...