1. 程式人生 > >Oracle_sql優化基礎——優化器總結

Oracle_sql優化基礎——優化器總結

oracle 優化器 cbo

優化器的基礎:

1、Oracle裏的優化器:

優化器是Oracle數據庫中內置的一個核心子系統,優化器的目的就是按照一定的判斷原則來得到它認為目標sql在當前情形下最高效的執行路徑,也就是說是為了得到目標sql的執行計劃。

Oracle數據庫的優化器分為:RBO和CBO兩種類型:

RBO:基於規則的優化器(在得到sql執行計劃時,RBO所用的判斷原則為一組內置的規則)

CBO:基於成本的優化器(在得到sql執行計劃時,CBO所用的判斷原則為成本,它會從目標sql諸多可能的執行路線中選擇成本值最小的一條來為其執行計劃)


註意:

①:從Oracle10G開始,RBO已不再被Oracle支持,但是RBO的相關實現代碼並麽有從Oracle代碼中移除,這也就是說在Oracle11GR2中依然可以通過修改優化器模式或使用rule hint來繼續使用RBO;


②:RBO的缺點很多,其中Oracle很多很好的特性、功能均不能再RBO下使用,因為他們均不被RBO支持。

有如下情形的即使修改了優化器模式或使用了RULE hint Oracle依然不會使用RBO(而是會強制使用CBO)

①:目標sql中涉及的對象有IOT(index organized table)

②:目標sql中涉及的對象有分區表

③:使用了並行查詢或者並行DML

④:使用了星型連接

⑤:使用了哈希鏈接

⑥:使用了索引快速全掃描

⑦:使用了函數索引

SQL> set autotrace traceonly ----開啟sql跟蹤,查看執行計劃

1.1、基於規則的優化器-RBO

在當前會話中將優化器模式修改為RULE,表示當前的session中啟用了RBO

SQL> alter session set optimizer_mode=‘RULE‘;


註意:在使用RBO的情況下可以通過等價改寫目標sql(加0或者空字符串的方式)來調整該sql的執行計劃

如:select * from emp_temp where mgr>100 and deptno+0>100; (deptno類型為number)

說明:

①:當目標sql有兩條或者兩條以上的執行計劃的等級值相同時,我們確實可以通過調整相關對象在數據字典緩存中的緩存順序來影響RBO對於其執行計劃的選擇;

②:如果RBO僅憑目標sql各條執行路徑等級值的大小就可以選擇出執行計劃,那麽無論怎麽調整相關對象在該sql的sql文本中的位置,對於該sql最終的執行計劃都不會有任何影響;


1.2、基於成本的優化器-CBO(從Oracle10G開始解析目標sql時默認使用CBO)

基於成本的優化器是指Oracle根據相關對象的統計信息計算出來的一個值,它實際上就是目標sql對應執行步驟的I/O CPU 和網絡資源的消耗量的一個估算值;

2、CBO的一些基本概念:

①:cardinality(集的優勢):是CBO特有的概念,它是指指定集合所包含的記錄數;它實際上表示對目標sql的某個具體執行步驟的執行結果所包含記錄數的估算。

②:可選擇率:也是CBO特有的概念,它是指施加指定謂詞條件後返回結果集的記錄數占未施加任何謂詞條件的原始結果集的記錄數的比率。可選擇率的取值範圍是0~1,它的值越小,就表名可選擇性越好,毫無疑問,可選擇率為1時的可選擇性是最差的;

③:可傳遞性:而是CBO特有的概念,其含義是指CBO可能會對原目標SQL做簡單的等價改寫,即在原目標SQL中加上根據sql現有的謂詞條件推算出來的新謂詞條件,這麽做的目的是提供更多的執行路徑給CBO做選擇,進而增加得到更高效執行計劃的可能性;

在Oracle裏,可傳遞性又分為如下三種情形:

①:簡單謂詞傳遞

比如原目標sql的謂詞條件是“t1.c1=t2.c1 and t1.c1=10”,則CBO可能會在這個謂詞條件中額外地加上“t2.c1=10”,即被修改成

t1.c1=t2.c1 and t1.c1=10 and t2.c1=10

②:連接謂詞傳遞

比如原來目標sql中的謂詞條件是“t1.c1=t2.c1 and t2.c1=t3.c1”,則CBO可能會在這個謂詞條件中額外地加上“t1.c1=t3.c1”,即被

修改成“t1.c1=t2.c1 and t2.c1=t3.c1 and t1.c1=t3.c1”

③:外連接謂詞傳遞

比如原目標sql中的謂詞條件是“t1.c1=t2.c1(+) and t1.c1=10”,則CBO可能會在這個謂詞條件中額外加上“t2.c1(+)=10”,即被修改成

“t1.c1(+) and t1.c1=10 and t2.c1(+)=10”


3、CBO的局限性:

①:CBO會默認目標sql語句where條件中出現的各個列之間是獨立的,沒有關聯關系

②:CBO會假設所有的目標sql都是單獨執行的,並且互不幹擾

③:CBO對直方圖統計信息有諸多限制

④:CBO在解析多表關聯的目標sql時,可能會漏選正確的執行計劃

#######################################################################


4、優化器的模式

在Oracle數據庫中,優化器的模式是由參數optimizer_mode的值來決定的,optimizer_mode的值可能是rule choose first_rows_n(n=1,10,100,1000) first_rows 或all_rows;

①:rule

rule表示Oracle將使用RBO來解析目標sql,此時目標sql中所涉及的各個對象的統計信息對於RBO來說將沒有任何作用。

②:choose

choose是Oracle9i的optimizer_mode的默認值,它表示Oracle在解析目標sql時到底是使用RBO還是使用CBO取決於該sql中所涉及的表對象是否有統計信息。

(只要改sql中所涉及的表對象中有一個有統計信息,那麽Oracle在解析該sql時就會使用CBO,如果該sql中所涉及的表對象均沒有統計信息,那麽Oracle就不會使用RBO)

③:first_rows_n(n=1,10,100,1000)

optimizer_mode可以是上面其中的任意一個值,其含義是指當optimizer_mode的值為first_rows_n(n=1,10,100,1000)時,Oracle會使用CBO來解析目標sql,且此時CBO在計算該sql的各條執行路徑的成本值時的側重點在於以最快的響應速度返回頭n (n=1,10,100,1000)條記錄。

④:first_rows

first_rows是一個在Oracle9i已經過時的參數,它表示Oracle在解析目標sql時會聯合使用CBO和RBO。這裏的聯合是大多數情況下,first_rows還是會使用CBO來解析目標sql;

⑤:all_rows

all_rows是Oracle10G以後後續版本數據庫版本中optimizer_mode的默認值,它表示Oracle會使用CBO來解析目標sql,且此時CBO在計算該sql的各條 執行路徑的成本值時的側重點在於最佳的吞吐量(即最小的系統I/O 和 CPU資源的消耗量);


《結果集》

結果集是指包含指定執行結果的集合,對於優化器而言(無論是RBO還是CBO)結果集和目標sql執行計劃的執行步驟相對應,一個執行步驟所產生的執行結果就是該執行步驟所對應的輸出結果集;


本文出自 “笨小孩的dba之路” 博客,請務必保留此出處http://fengfeng688.blog.51cto.com/4896812/1952652

Oracle_sql優化基礎——優化器總結