我們都知道Oracle中的每壹條SQL語句在執行前都需要進行解析,分為軟解析和硬解析。Oracle中有兩種類型的SQL語句,壹種是?DDL語句(數據定義語言)從來不用,就是每次執行都需要硬解析。還有壹類是DML語句(數據操作語言),會根據情況選擇要麽硬解析,要麽軟解析。
DML:插入、更新、刪除、選擇
DDL:創建、刪除、改變?
壹個。?SQL?分析過程
Oracle將分幾個步驟處理該SQL:
1,語法檢查(語法?檢查):?檢查此sql的拼寫是否符合語法。
2、語義檢查(semantic?檢查):?比如檢查sql語句中的access對象是否存在,用戶是否有相應的權限。
3.簡述sql語句:?使用內部算法解析sql,生成解析樹(parse?樹)和執行計劃(執行?計劃).
4.執行sql並返回結果(execute?然後呢。返回)
兩個。?分析過程的詳細說明
2.1?語法檢測
判斷壹條SQL語句的語法是否符合SQL的規範,比如執行:
SQL & gt?selet?*?從哪裏?emp
我們可以看到,因為Select關鍵字缺少壹個“c”,所以這條語句無法通過語法檢查這壹步。
2.2?語義檢查
解析語法正確的SQL語句的第二步是判斷SQL語句訪問的表和列是否準確。用戶是否有權訪問或更改相應的表或列??例如,下面的語句:
SQL & gt?選擇?*?從哪裏?emp
選擇?*?從哪裏?電磁脈沖
*
錯誤?在哪裏?線?1:
ORA-00942:?桌子?還是?觀點?是嗎?不是嗎?存在
因為查詢用戶沒有要訪問的emp對象,所以SQL語句無法通過語義檢查。
2.3?分析(剖析)
2.3.1?解析主要分為三種類型:
1、辛苦?解析?(硬解析)
2、軟?解析?(軟解析)
3、軟?軟?解析(有些資料裏好像沒有這個)
努力?解析:?就是上面提到的完全重新解析提交的Sql從頭開始(在Shared?當在池中沒有找到它時,將執行該操作),並且總是有五個執行步驟:
1:語法分析
2.權限和對象檢查
3:?查看* * *共享池,看看有沒有之前完全解決的壹模壹樣的。如果存在,直接跳過4和5,運行Sql。這時候軟了嗎?解析。
4:選擇壹個執行計劃
5.生成執行計劃
註意:創建解析樹和生成執行計劃對於sql執行來說是開銷很大的操作,所以應該避免硬解析,盡可能使用軟解析。這就是為什麽在許多項目中,鼓勵開發人員對具有相同功能的代碼保持代碼壹致性,並在程序中使用更多的綁定變量。
軟?解析:?只是如果是合租呢?努力?在池中找到相同的Sql解析結果後,將被跳過。解析的下兩個步驟。
軟?軟?解析:?實際上,在設置Session_Cursor_Cache參數時,遊標直接緩存在當前會話的PGA中。解析的時候只需要分析它的語法和權限對象就可以去PGA找了。如果找到完全相同的光標,可以直接取結果,也就是實現了?軟?軟?解析。
2.3.2?解析的步驟可以分為兩個步驟:
1)驗證SQL語句是否完全壹致。
在這壹步,Oracle會使用HASH函數計算傳入的SQL語句的HASH值,然後與* * *共享池中現有語句的HASH值進行比較,看是否存在壹壹對應的關系。現有數據庫中SQL語句的哈希值可以通過訪問vsqlarea、v$sqltext等數據字典中的HASH_VALUE列獲得。
如果SQL語句的哈希值壹致,那麽ORACLE實際上需要再次測試SQL語句的語義,以確定它們是否壹致。那麽Oracle為什麽需要再次測試語句文本呢?SQL語句的哈希值不是已經對應了嗎?事實上,即使SQL語句的哈希值已經匹配,也不代表這兩條SQL語句已經可以享用了。
例如,如果用戶SYS有自己的表EMP,他將執行查詢語句:select?*?從哪裏?emp?用戶系統也有EMP表,也想查詢select?*?從哪裏?emp這樣他們兩個語句在文本上完全壹樣,哈希值也會壹樣,但是因為查詢涉及的相關表不壹樣,實際上享受不到。
SQL & gt?康恩?/?作為?sysdba
已連接。
SQL & gt?秀?用戶
用戶?為了什麽?"系統"
SQL & gt?創造?桌子?emp?(?x?int?)?;
表已創建。
SQL & gt?選擇?*?從哪裏?emp
未選擇任何行。
SQL & gt?康恩?系統/管理;
已連接。
SQL & gt?創造?桌子?emp?(?x?int?);
表已創建。
SQL & gt?選擇?*?從哪裏?emp
未選擇任何行。
SQL & gt?選擇?地址,散列值,?處決?sql_text?從哪裏?v$sql?在哪裏?upper(sql_text)?比如?選擇?*?從哪裏?EMP % ';
地址?散列值?執行SQL_TEXT
- ?-
2769AE641745700775?1?選擇?*?從哪裏?emp?
2769AE641745700775?1?選擇?*?從哪裏?電磁脈沖
2?行?已選中。
從結果可以看出,這兩個查詢的句子文本和哈希值是相同的,但是由於查詢的對象不同,所以無法共享,不同情況的句子還是需要硬解析。所以在檢查* * *共享池* * *的SQL語句時,需要根據具體情況決定。
可以進壹步查詢v$sql_shared_cursor,了解sql為什麽不能* * *享受:
SQL & gt選擇?地址,auth_check_mismatch,translation_mismatch,optimizer_mismatch?
從哪裏?v$sql_shared_cursor?在哪裏?地址?在?(?
選擇?地址?從哪裏?v$sql?在哪裏?upper(sql_text)?比如?選擇?*?從哪裏?EMP% '?)?
地址?答?t?O
- ?- ?- ?- ?
2769AE64?n?n?普通
2769AE64?y?y?普通
翻譯_不匹配?指示SQL遊標中涉及的數據對象不同;
AUTH _ CHECK _失配?指示同壹SQL語句的轉換不匹配。
優化器_不匹配?代表會話的優化器環境是不同的。
2)?驗證SQL語句執行環境是否相同。
比如同樣的SQL語句,壹個查詢會話加/*+?first_rows?提示*/,另壹用戶添加/*+?所有行?*/提示,它們將產生不同的執行計劃,即使它們查詢的是相同的數據。
經過上面的檢查,如果SQL語句壹致,那麽原來SQL語句的執行計劃和優化方案就會被重用,也就是我們通常所說的軟解析。如果SQL語句沒有找到相同的副本,那麽就需要進行硬解析。
Oracle根據提交的SQL語句查詢對應的數據對象是否有統計信息。如果有統計數據,CBO將利用這些統計數據生成所有可能的執行計劃(可能有數千個)和相應的成本,最終選擇成本最低的執行計劃。如果所查詢的數據對象沒有統計信息,則根據RBO的默認規則選擇相應的執行計劃。這壹步也是解析中最耗費資源的,要盡量避免硬解析。至此,解析的所有步驟都已經完成,Oracle將根據解析生成的執行計劃執行SQL語句並提取相應的數據。?
2.4?執行sql並返回結果(Execute?然後呢。返回)
三個。?綁定變量?
用過的Bind?Var能提升性能主要是因為可以避免不必要的硬分析(硬?Parse)節省時間和大量CPU資源。
當客戶端向Oracle提交Sql時,Oracle?首先會對其進行解析,然後將解析結果提交給優化器進行優化,得到Oracle認為的最優查詢。計劃,然後按照這個最優計劃執行這個Sql語句(當然如果只需要軟解析的話步驟會少壹些)。
然而,當甲骨文收到?客戶端提交的Sql之後,會先在* * *池中共享(共享?Pool)來查找是否有之前已經解析過的Sql與剛剛收到的完全相同(註意這裏是完全相同的,要求語句上的字符級別和涉及的對象都完全相同)。當發現相同時,解析器不會在這裏解析新的Sql,而是直接使用之前解析的結果。這節省了解析時間和解析過程中消耗的CPU資源。尤其是大量的短Sql運行在OLTP中,效果會更加明顯。因為壹個兩個Sql的時間可能感覺不到多少,但是當量大了以後,感覺會更明顯。