Oracle_優化器使用(oracle11g)


一:優化器介紹

  優化器(optimizer)是oracle數據庫內置的一個核心子系統。優化器的目的是按照一定的判斷原則來得到它認為的目標SQL在當前的情形下的最高效的執行路徑,也就是為了得到目標SQL的最佳執行計划。依據所選擇執行計划時所用的判斷原則,oracle數據庫里的優化器又分為RBO(基於原則的優化器)和CBO(基於成本的優化器,SQL的成本根據統計信息算出)兩種。

  • RBO

  Oracle會在代碼里事先為各種類型的執行路徑定一個等級,一共15個等級,從等級1到等級15,oracle認為等級1的執行路徑是效率最高的,等級15是執行效率最差的。對於等級相同的執行計划,oracle根據目標對象的在數據字典中緩存的順序判斷選擇哪一種執行計划。RBO是一種適合於OLTP類型SQL語句的優化器。相對於CBO而言,RBO有着先天的缺陷,一旦SQL語句的執行計划出現問題,將很難調整。那么RBO執行計划出現問題,怎么調整目標SQL的執行計划呢?一般有如下方法:等價改寫目標SQL,比如在where條件對number和date類型的列添加0(deptno+0>100),varchar2或char類型的列可以添加一個“空字符”,例如“||”。對於多表連接的SQL,可以改變from表的連接順序(RBO會按照從右往左的順序決定誰是驅動表,誰是被驅動表。)來達到改變目標SQL執行計划的目的。我們也可以改變相關對象在數據字典中緩存的順序(創建順序),來改變執行計划。RBO最大的缺點是以oracle內置代碼的規則作為判斷標准,而並沒有考慮到實際目標表的數據量以及數據分布情況。

  • CBO

  CBO選擇執行計划時,以目標SQL成本為判斷原則,CBO會選擇一條執行成本最小的執行計划作為SQL的執行計划,各條執行路徑的成本通過目標SQL語句所涉及的表、索引、列等的統計信息算出。這里的成本是oracle通過相關對象的統計信息計算出來的一個值,它實際上代表目標SQL對應執行步驟所消耗的IO、CPU、網絡資源(針對於dblink下的分布式數據庫系統而言)的消耗量,oracle會把網絡資源的消耗量計算在IO成本內,實際上你看到的成本為IO、CPU資源,另外需要注意的是,oracle在未引入系統統計信息之前,CBO所計算的成本值實際全是基於IO計算的。

  1、集的勢(cardinality)

  Cardinality是CBO特有的概念,指集合所包含的記錄數,即結果集行數。Cardinality實際上表示對目標SQL某個具體執行步驟的執行結果所包含的記錄數的估算,當然,如果針對整個目標SQL,那么此時的cardinality就表示對該SQL最終執行結果所包含的記錄數的估算。Cardinality和成本值得估算息息相關,因為oracle得到的制定結果集所需要消耗的IO資源可以近似的看成隨着結果集所包含的記錄數遞增而遞增。所以,SQL編寫的一個原則就是“盡早的過濾更多的數據”。

  2、可選擇率(Selectivity)

  Selectivity也是CBO特有的概念,它是指“施加指定謂語條件后返回的結果集的記錄數占未施加任何謂語條件的原始結果集的記錄數的比率”,取值范圍為0~1,其值越小,代表可選擇性越好。Selectivity也可成本值得估算息息相關,可選擇率越大,意味着所返回的結果集的cardinality越大,所以估算的成本就越大。實際上CBO就是利用selectivity來計算對應結果集的cardinality的,即:Computed cardinality=original*selectivity

  Cardinility和selectivity的值會直接影響CBO對於相關執行步驟成本的估算,進而影響CBO對於目標SQL的執行計划的選擇。

  3、可傳遞性

  可傳遞性也是CBO的特有屬性,它是查詢轉換中所做的第一件事情,其含義是CBO會對目標SQL做等價改寫,進而提供更多的執行路徑給目標CBO,增加得到最佳執行計划的可能性。RBO不會對目標SQL做等價改寫。Oracle里可傳遞性分為以下3種情況:

  1)簡單謂語傳遞

  比如原目標SQL中的謂語條件是“t1.c1=t2.c1 and t1.c1=10”,則CBO可能會給謂語條件額外加上“t2.c1=10”。

  2)連接謂語傳遞

  比如原目標SQL中的謂語條件是“t1.c1=t2.c1 and t2.c1=t3.c1”,則CBO可能會給謂語條件額外加上“t1.c1=t3.c1”。

  3)外鏈接謂語傳遞

  比如原目標SQL中的謂語條件是“t1.c1=t2.c1(+) and t1.c1=10”,則CBO可能會給謂語條件額外加上“t2.c1(+)=10”。

  4、CBO的局限性

  1)CBO會默認目標SQL語句where條件中出現的各個列之間出現是獨立的,沒有任何關聯。並且CBO會根據這個前提條件來計算selectivity和cardinality,進而估算成本並選擇執行計划。但是這種假設並不全是正確的,生產中列與列之間存在關聯的現象並不罕見。目前可以用來緩解上述負面影響的方法是使用動態采樣和多列統計信息。但動態采樣的准確性取決於采樣數據的質量以及數量,而多列統計信息並不適合用於多表之間有關聯的情形,所以這兩種方法只能算是緩解,並不算是完美的解決方案。

  2)CBO會假設所有的目標SQL都是獨立運行的,並且互不干擾,但實際情況卻不完全是這樣。

  3)CBO對直方圖統計信息有多方限制。主要體現在如下2個方面:

    (1)在oracle 12c之前,frequency類型的直方圖所對應的bucket的數量不能超過254,這樣如果列的distinct數量超過254,oracle就會使用height balanced類型的直方圖。對於height balanced類型的直方圖而言,oracle不會記錄所有的nonpopular value的值,所以此種情況下CBO選錯執行計划的概率會比frequency類型的情形要高。

    (2)在oracle數據庫里,如果針對文本類型的字段手機直方圖統計信息,則oracle只會將文本的前32個字符(實際只取前15個)取出來並將其轉換為浮點數,然后將浮點數作為上述文本字段的直方圖統計信息記錄在數據字典里。

  4)CBO在解析多表關聯的目標SQL時,可能會漏選正確的執行計划。在oracle 11gR2中,CBO在解析這種多表關聯的目標SQL時,所考慮的各個表的連接順序的總和受隱含參數_OPTIMIZER_MAX_PERMUTATIONS的限制。這意味着目標SQL不管有多少種連接順序,CBO最多只考慮其中根據_OPTIMIZER_MAX_PERMUTATIONS計算出來的有限種可能性。

 

二:oracle 11g優化器

  Oracle 11g使用基於代價的優化方式(CBO),這里的代價主要指CPU和內存,優化器只要參照的是表及索引的統計信息。

  • 創建表(plan_table)

SQL> @$ORACLE_HOME/rdbms/admin/utlxplan.sql;-----創建oracle EXPLNAN PLAN計划使用的表(plan_table),在sqlplus環境下執行UTLXPLAN.SQL腳本:
  • 設置語句的執行計划

explain plan [set statement_id [=] <string literal>] [into <table_name>] for <sql_statement>;-----把某條sql語句執行計划分析數據插入plan_table表
  • plan_table字段解釋

 

 

    


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM