oracle中每條sql在執行前都要解析,解析分為硬解析、軟解析、軟軟解析。
oracle會快取dml語句,相同的dml語句會進行軟解析。但不會快取ddl語句,所以ddl每次都做硬解析。硬解析是乙個很耗時的操作,所以應用程式內部很少執行執行ddl。ddl一般在部署前執行。
sql語句執行步驟:
1.語法檢查(syntax check)
2.語義檢查(symantic check): 物件是否存在,是否有許可權。
3.sql解析(parse): 利用內部演算法對sql進行解析,生成解析樹及執行計畫。
4.執行sql,返回結果(execute and return)
首先了解一下sql解析時用到的記憶體結構——shared pool:
shared pool是一塊記憶體池,裡邊又被分成了很多小的區塊,每個塊有他們的作用
1.free (空閒)
2.library cache (庫快取,快取sql語句以及sql所對應的執行計畫)
3.row cache (字典快取——庫里有多少表,多少使用者,多少個列,列的名字,列的資料型別,每個表多大等等都屬於資料庫自身資訊。)
乙個sql 語句,進入到資料庫後,server process 會拿著sql語句到shared pool中的library cache 裡邊去找,看sql語句以前是否有執行過。也就是在library cache 裡面看有沒有這條sql語句以及sql語句所對應的執行計畫。(此過程是通過對傳遞進來的sql語句使用hash函式運算得出hash值,與共享池中現有語句的hash值進行比較看是否一一對應。現有資料庫中sql語句的hash值我們可以通過訪問vsql、vsql、vsqlarea、v$sqltext等資料字典中的hash_value列查詢得出。)
parse主要分為三種:
1.hard parse (硬解析)
2.soft parse (軟解析)
3.soft soft parse
hard parse:對提交的sql完全重新從頭進行解析(當在shared pool中找不到時候將會進行此操作),總共有一下5個執行步驟:
1.語法分析
2.許可權與物件檢查
3.在共享池中檢查是否有完全相同的之前完全解析好的. 如果存在,直接跳過4和5,執行sql, 此時算soft parse.
4.選擇執行計畫
5.產生執行計畫
注:建立解析樹、生成執行計畫對於sql的執行來說是開銷昂貴的動作,所以,應當極力避免硬解析,盡量使用軟解析。這就是在很多專案中,倡導開發設計人員對功能相同的**要努力保持**的一致性,以及要在程式中多使用繫結變數的原因。
soft parse:在shared pool中找到了與之完全相同的sql解析好的結果後會跳過hard parse中的後面的兩個步驟。
soft soft parse:當設定了session_cursor_cache這個引數之後,cursor被直接cache在當前session的pga中的,在解析的時候只需要對其語法分析、許可權物件分析之後就可以轉到pga中查詢了,如果發現完全相同的cursor,就可以直接去取結果了,也就就是實現了 soft soft parse.
如果sql語句的hash值一致,那麼oracle事實上還需要對sql語句的語義進行再次檢測,以決定是否一致。那麼為什麼oracle需要再次對語句文字進行檢測呢?不是sql語句的hash值已經對應上了?事實上就算是sql語句的hash值已經對應上了,並不能說明這兩條sql語句就已經可以共享了。
例如:假如使用者sys有自己的一張表emp,他要執行查詢語句:select * from emp; 使用者system也有一張emp表,同樣要查詢select * from emp;這樣他們兩條語句在文字上是一模一樣的,他們的hash值也會一樣,但是由於涉及到查詢的相關表不一樣,他們事實上是無法共享的.
下面我們來看實驗:
資料庫版本:oracle database 10g enterprise edition release 10.2.0.1.0 - prod
create table test as select * from user_objects where 1<>1;
begindbms_stats.gather_table_stats('tough','test');
end;
alter system flush shared_pool;
select * from test where object_id=20;select * from test where object_id=30;
select * from test where object_id=40;select * from test where object_id=40;
select * from test where object_id=50;
select * from test where object_id=50;
select * from test where object_id=50;
select * from test where object_id=50;
begin檢視解析情況:for i in 1 .. 4 loop
execute immediate 'select * from test where object_id=:i'
using i;
end loop;
end;
select sql_text, s.parse_calls, loads, executionssql_textparse_callsloadsexecutionsfrom v$sql s
where sql_text like 'select * from test where object_id%'
order by 1, 2, 3, 4;
select * from test where object_id=20 11
1select * from test where object_id=30 11
1select * from test where object_id=40 21
2select * from test where object_id=50 41
4select * from test where object_id=:i11
4 object_id=20 -> 因為沒有快取此條sql,所以硬解析
object_id=30 -> 因為沒有快取此條sql,所以硬解析
object_id=40 -> 因為第一次執行已經快取此條sql,所以軟解析次數為2,硬解析次數為1
object_id=50 -> 因為第一次執行已經快取此條sql,所以軟解析次數為4,硬解析次數為1
object_id=:i -> 用了動態繫結變數,儘管執行了4次,但只做了一次硬解析和一次軟解析
字段解釋:
parse_calls - 解析的次數
loads - 硬解析的次數
executions - 執行的次數
硬解和軟解的區別
q 什麼是硬解?a 硬解是要機器中的專門的解碼晶元來完成,質量因廠家的技術能力而定,部分廠商技術實力強,相容性和解碼效果做的比較好,而有些廠商技術實力稍差,相容性和解碼效果做的就不盡如意。q 什麼是軟解?a 軟解就是用cpu來解碼,需要cpu的效能與處理能力較強,但對流 格式相容性比較好,因為軟解庫...
Oracle的硬解析和軟解析
提到軟解析 soft parse 和硬解析 hard parse 就不能不說一下oracle對sql的處理過程。當你發出一條sql語句交付oracle,在執行和獲取結果前,oracle對此sql將進行幾個步驟的處理過程 1 語法檢查 syntax check 檢查此sql的拼寫是否語法。2 語義檢查...
Oracle的硬解析和軟解析
提到軟解析 soft prase 和硬解析 hard prase 就不能不說一下oracle對sql的處理過程。當你發出一條sql語句交付oracle,在執行和獲取結果前,oracle對此sql將進行幾個步驟的處理過程 1 語法檢查 syntax check 檢查此sql的拼寫是否語法。2 語義檢查...