ORACLE的優化器

2022-08-09 15:33:17 字數 4298 閱讀 7230

優化器有時也被稱為查詢優化器,這是因為查詢是影響資料庫效能最主要的部分,不要以為只有select語句是查詢。實際上,帶有任何where條件的dml(insert、update、delete)語句中都包含查詢要求,在後面的文章中,當說到查詢時,不一定只是指select語句,也有可能指dml語句中的查詢部分。優化器是所有關聯式資料庫引擎中的最神秘、最富挑戰性的部件之一,從效能的角度看也是最重要的部分,它效能的高低直接關係到資料庫效能的好壞。

我們知道,sql語句同其它語言(如c語言)的語句不一樣,它是非過程化(non-procedural)的語句,即當你要取資料時,不需要告訴資料庫通過何種途徑去取資料,如到底是通過索引取資料,還是應該將表中的每行資料都取出來,然後再通過一一比較的方式取資料(即全表掃瞄),這是由資料庫的優化器決定的,這就是非過程化的含義,也就是說,如何取資料是由優化器決定,而不是應用開發者通過程式設計決定。在處理sql的select、update、insert或delete語句時,oracle 必須訪問語句所涉及的資料,oracle的優化器部分用來決定訪問資料的有效路徑,使得語句執行所需的i/o和處理時間最小。

為了實現乙個查詢,核心必須為每個查詢定製乙個查詢策略,或為取出符合條件的資料生成乙個執行計畫(execution plan)。典型的,對於同乙個查詢,可能有幾個執行計畫都符合要求,都能得到符合條件的資料。例如,參與連線的表可以有多種不同的連線方法,這取決於連線條件和優化器採用的連線方法。為了在多個執行計畫中選擇最優的執行計畫,優化器必須使用一些實際的指標來衡量每個執行計畫使用的資源(i/0次數、cpu等),這些資源也就是我們所說的代價(cost)。如果乙個執行計畫使用的資源多,我們就說使用執行計畫的代價大。以執行計畫的代價大小作為衡量標準,優化器選擇代價最小的執行計畫作為真正執行該查詢的執行計畫,並拋棄其它的執行計畫。

在oracle的發展過程中,一共開發過2種型別的優化器:基於規則的優化器和基於代價的優化器。這2種優化器的不同之處關鍵在於:取得代價的方法與衡量代價的大小不同。現對每種優化器做一下簡單的介紹:

基於規則的優化器 -- rule based (heuristic) optimization(簡稱rbo):

oracle把乙個代價引擎(cost engine)整合到資料庫核心中,用來估計每個執行計畫需要的代價,該代價將每個執行計畫所耗費的資源進行量化,從而cbo可以根據這個代價選擇出最優的執行計畫。乙個查詢耗費的資源可以被分成3個基本組成部分:i/o代價、cpu代價、network代價。i/o代價是將資料從磁碟讀入記憶體所需的代價。訪問資料報括將資料檔案中資料塊的內容讀入到sga的資料快取記憶體中,在一般情況下,該代價是處理乙個查詢所需要的最主要代價,所以我們在優化時,乙個基本原則就是降低查詢所產生的i/o總次數。cpu代價是處理在記憶體中資料所需要的代價,如一旦資料被讀入記憶體,則我們在識別出我們需要的資料後,在這些資料上執行排序(sort)或連線(join)操作,這需要耗費cpu資源。

對於需要訪問跨節點(即通常說的伺服器)資料庫上資料的查詢來說,存在network代價,用來量化傳輸操作耗費的資源。查詢遠端表的查詢或執行分布式連線的查詢會在network代價方面花費比較大。

在使用cbo時,需要有表和索引的統計資料(分析資料)作為基礎資料,有了這些資料,cbo才能為各個執行計畫計算出相對準確的代價,從而使cbo選擇最佳的執行計畫。所以定期的對錶、索引進行分析是絕對必要的,這樣才能使統計資料反映資料庫中的真實情況。否則就會使cbo選擇較差的執行計畫,影響資料庫的效能。分析操作不必做的太頻繁,一般來說,每星期一次就足夠了。切記如果想使用cbo,則必須定期對錶和索引進行分析。

對於分析用的命令,隨著資料庫版本的公升級,用的命令也發生了變換,在oracle 8i以前,主要是用analyze命令。在oracle 8i以後,又引入了dbms_stats儲存包來進行分析。幸運的是從oracle 10g以後,分析工作變成自動的了,這減輕的dba的負擔,不過在一些特殊情況下,還需要一些手工分析。

如果採用了cbo優化器,而沒有對錶和索引進行分析,沒有統計資料,則oracle使用預設的統計資料(至少在oracle 9i中是這樣),這可以從oracle的文件上找到。使用的預設值肯定與系統的實際統計值不一致,這可能會導致優化器選擇錯誤的執行計畫,影響資料庫的效能。

要注意的是:雖然cbo的功能隨著oracle新版本的推出,功能越來越強,但它不是能包治百病的神藥,否則就不再需要dba了,那我就慘了!!!實際上任何乙個語句,隨著硬體環境與應用資料的不同,該語句的執行計畫可能需要隨之發生變化,這樣才能取得最好的效能。所以有時候不在具體的環境下而進行sql效能調整是徒勞的。

在oracle8i推出的時候,oracle極力建議大家使用cbo,說cbo有種種好處,但是在那是oracle開發的應用系統還是使用基於規則的優化器,從這件事上我們可以得出這樣的結論:1) 如果團隊的資料庫水平很高而且都熟悉應用資料的特點,rbo也可以取得很好的效能。2)cbo不是很穩定,但是乙個比較有前途的優化器,oracle極力建議大家用是為了讓大家盡快發現它的bug,以便進一步改善,但是oracle為了對自己開發的應用系統負責,他們還是使用了比較熟悉而且成熟的rbo。從這個事情上給我們的啟發就是:我們在以後的開發中,應該盡量採用我們熟悉並且成熟的技術,而不要一味的採用新技術,一味採用新技術並不一定能開發出好的產品。幸運的是從oracle 10g後,cbo已經足夠的強大與智慧型,大家可以放心的使用該技術,因為oracle 10g後,oracle自己開發的應用系統也使用cbo優化器了。而且oracle規定,從oracle 10g開始,開始廢棄rbo優化器。這句話並不是指在oracle 10g中不能使用rbo,而是從oracle 10g開始開始,不再為rbo的bug提供修補服務。

在上面的第2個例子中,如果採用cbo優化器,它就會考慮emp表的行數,deptno列的統計資料,發現對該列做查詢會查詢出過多的資料,並且考慮db_file_multiblock_read_count引數的設定,發現用全表掃瞄的代價比用索引掃瞄的代價要小,從而使用全表掃瞄從而取得良好的執行效能。

判斷當前資料庫使用何種優化器:

主要是由optimizer_mode初始化引數決定的。該引數可能的取值為:first_rows_[1 | 10 | 100 | 1000] |first_rows|all_rows|choose| rule。具體解釋如下:

rule為使用rbo優化器。

choose則是根據實際情況,如果資料字典中包含被引用的表的統計資料,即引用的物件已經被分析,則就使用cbo優化器,否則為rbo優化器。

all_rows為cbo優化器使用的第一種具體的優化方法,是以資料的吞吐量為主要目標,以便可以使用最少的資源完成語句。

first_rows為優化器使用的第二種具體的優化方法,是以資料的響應時間為主要目標,以便快速查詢出開始的幾行資料。

first_rows_[1 | 10 | 100 | 1000] 為優化器使用的第三種具體的優化方法,讓優化器選擇乙個能夠把響應時間減到最小的查詢執行計畫,以迅速產生查詢結果的前 n 行。該引數為oracle 9i新引入的。

從oracle v7以來,optimizer_mode引數的預設設定應是"choose",即如果對已分析的表查詢的話選擇cbo,否則選擇rbo。在此種設定中,如果採用了cbo,則預設為cbo中的all_rows模式。

注意:即使指定資料庫使用rbo優化器,但有時oracle資料庫還是會採用cbo優化器,這並不是oracle的bug,主要是由於從oracle 8i後引入的許多新特性都必須在cbo下才能使用,而你的sql語句可能正好使用了這些新特性,此時資料庫會自動轉為使用cbo優化器執行這些語句。

什麼是優化

優化是選擇最有效的執行計畫來執行sql語句的過程,這是在處理任何資料的語句(select,insert,update或delete)中的乙個重要步驟。對oracle來說,執行這樣的語句有許多不同的方法,譬如說,將隨著以什麼順序訪問哪些表或索引的不同而不同。所使用的執行計畫可以決定語句能執行得有多快。oracle中稱之為優化器(optimizer)的元件用來選擇這種它認為最有效的執行計畫。

由於一系列因素都會會影響語句的執行,優化器綜合權衡各個因素,在眾多的執行計畫中選擇認為是最佳的執行計畫。然而,應用設計人員通常比優化器更知道關於特定應用的資料特點。無論優化器多麼智慧型,在某些情況下開發人員能選擇出比優化器選擇的最優執行計畫還要好的執行計畫。這是需要人工干預資料庫優化的主要原因。事實表明,在某些情況下,確實需要dba對某些語句進行手工優化。

注:從oracle的乙個版本到另乙個版本,優化器可能對同一語句生成不同的執行計畫。在將來的oracle 版本中,優化器可能會基於它可以用的更好、更理想的資訊,作出更優的決策,從而導致為語句產生更優的執行計畫。 

Oracle認證 Oracle優化器的優化方式

oracle是世界領先的資訊管理軟體開發商,因其複雜的關聯式資料庫產品而聞名。本文介紹oracle優化器,它是乙個非常好用的工具。oracle在執行乙個sql之前,首先要分析一下語句的執行計畫,然後再按執行計畫去執行。分析語句的執行計畫的工作是由優化器 optimizer 來完成的。不同的情況,一條...

Oracle的優化器

一 目的 1 說一說oracle的optimizer及其相關的一些知識。2 回答一下為什麼有時乙個表的某個字段明明有索引,當觀察一些sql的執行計畫時,發現確不走索引的問題。3 如果你對 first rows all rows這兩種模式有疑惑時也可以看一下這篇文章。oracle在執行乙個sql之前,...

ORACLE的優化器

a.rule 基於規則 b.cost 基於成本 c.choose 選擇性 設定預設的優化器,可以通過對init.ora檔案中optimizer mode引數的各種宣告,如rule,cost,choose,all rows,first rows 你當然也在sql句級或是會話 session 級對其進行...