oracle 數據庫sql 語句處理過程

14.1SQL語句處理過程
在進行SQL語句處理優化前,需要先熟悉和了解SQL語句的處理過程。
每種類型的語句在執行時都需要如下階段:
第1步: 創建游標。
第2步: 分析語句。
第5步: 綁定變量。
第7步: t運行語句。
第9步: 關閉游標。
如果使用了并行功能,還會包含下面這個階段:
第6步: 并行執行語句。
如果是查詢語句,則需要幾個額外的步驟:
第3步: 描述查詢的結果集。
第4步: 定義查詢的輸出數據。
第8步: 取查詢出來的行。
第1步 創建游標(Create a Cursor) :由程序接口調用創建一個游標(cursor)。任何SQL語句都會創建它,特別在運行DML語句時,都是自動創建游標的,不需要開發人員干預。多數應用中,游標的創建是自動的。然而,在預編譯程序中創建的游標,可能是隱含的,也可能顯式的創建。在存儲過程中也是這樣的。
第2步分析語句(Parse the Statement):在語法分析期間,SQL語句從用戶進程傳送到Oracle,SQL語句經語法分析后,SQL語句本身與分析的信息都被裝入到共享SQL區。在該階段中,可以解決許多類型的錯誤。
語法分析分別執行下列操作:
(1)翻譯SQL語句,驗證它是合法的語句,即書寫是否正確。
(2)實現數據字典的查找,以驗證是否符合表和列的定義。
(3)在所要求的對象上獲取語法分析鎖,使得在語句的語法分析過程中不改變這些對象的定義。驗證為存取所涉及的模式對象所需的權限是否滿足。決定此語句最佳的執行計劃,將它裝入共享SQL區。
以上任何一步出錯誤,都將導致語句報錯,中止執行。
只有在共享池中不存在等價SQL語句的情況下,才對SQL語句作語法分析。在這種情況下,數據庫內核重新為該語句分配新的共享SQL區,并對語句進行語法分析。進行語法分析需要耗費較多的資源,所以要盡量避免進行語法分析,這是優化的技巧之一。
Oracle只對每個SQL語句翻譯一次,在以后再次執行該語句時,只要該語句還在共享SQL區中,就可以避免對該語句重新進行語法分析,也就是此時可以直接使用其對應的執行計劃對數據進行存取。這主要是通過綁定變量(bind variable)實現的,也就是常說的共享SQL,后面會給出共享SQL的概念。
雖然語法分析驗證了SQL語句的正確性,但語法分析只能識別在SQL語句執行之前所能發現的錯誤(如書寫錯誤、權限不足等)。因此,有些錯誤通過語法分析是抓不到的。例如,在數據轉換中的錯誤或在數據中的錯(如企圖在主鍵中插入重復的值)以及死鎖等均是只有在語句執行階段期間才能遇到和報告的錯誤或情況。 查詢與其它類型的SQL語句不同,因為在成功執行后作為結果將返回數據。
第3步 描述查詢結果;描述階段只有在查詢結果的各個列是未知時才需要;例如,當查詢由用戶交互地輸入需要輸出的列名。在這種情況要用描述階段來決定查詢結果的特征(數據類型,長度和名字)。
第4步定義查詢的輸出數據:在查詢的定義階段,指定與查詢出的列值對應的接收變量的位置、大小和數據類型,這樣通過接收變量就可以得到查詢結果。如果必要的話,Oracle會自動實現數據類型的轉換。這是將接收變量的類型與對應的列類型相比較決定的。
第5步: 綁定變量:Oracle知道了SQL語句的意思,但仍沒有足夠的信息用于執行該語句。Oracle 需要得到在語句中列出的所有變量的值。在該例中,Oracle需要得到對列進行限定的值。得到這個值的過程就叫綁定變量(binding variables)。
此過程稱之為將變量值捆綁進來。程序必須指出可以找到該數值的變量名(該變量被稱為捆綁變量,變量名實質上是一個內存地址,相當于指針)。應用的最終用戶可能并沒有發覺他們正在指定捆綁變量,因為Oracle 的程序可能只是簡單地指示他們輸入新的值,其實這一切都在程序中自動做了。
因為你指定了變量名,在你再次執行之前無須重新捆綁變量。你可以改變綁定變量的值,而Oracle在每次執行時,僅僅使用內存地址來查找此值。
如果Oracle 需要實現自動數據類型轉換的話(除非它們是隱含的或缺省的),你還必須對每個值指定數據類型和長度。
第6步:并行執行語句(Parallelize the Statement ):Oracle 可以在DML語句中執行相應并行查詢操作,對某些DDL操作,如創建索引、用子查詢創建表、在分區表上的操作,可以執行并行操作。并行化可導致多個服務器進程為同一個SQL語句工作,使該SQL語句可以快速完成,但是會耗費更多的資源,所以除非很有必要,否則不要使用并行查詢。
第7步執行語句:Oracle擁有所有需要的信息與資源,可以真正運行SQL語句了。如果該語句為SELECT查詢或INSERT語句,則不需要鎖定任何行,因沒有數據需要被改變。如果語句為UPDATE或DELETE語句,則該語句影響的所有行都被鎖定,防止該用戶提交或回滾之前,別的用戶對這些數據進行修改。這保證了數據的一致性。
對于某些語句,可以指定執行的次數,這稱為批處理。指定執行N次,則綁定變量與定義變量被定義為大小為N的數組的開始位置,這種方法可以減少網絡開銷,也是優化的技巧之一。
第8步取出查詢的行:在fetch階段,行數據被取出來,每個后續的存取操作檢索結果集中的下一行數據,直到最后一行被取出來。上面提到過,批量的fetch是優化的技巧之一。
第9步關閉游標,SQL語句處理的最后一個階段就是關閉游標。
14.2SQL解析共享原理
Oracle將執行過的SQL語句存放在內存的共享池(shared buffer pool)中,可以被所有的數據庫用戶共享。當執行一個SQL語句(有時被稱為一個游標)時,如果它和之前的執行過的語句完全相同,Oracle就能很快獲得已經被解析的語句以及最好的執行路徑。這個功能大大地提高了SQL的執行性能并節省了內存的使用。
為了不重復解析相同的SQL語句,在第一次解析之后,Oracle將SQL語句存放在內存中。這塊位于系統全局區域SGA的共享池中的內存可以被所有的數據庫用戶共享。因此,當執行一個SQL語句(有時被稱為一個游標)時,如果它和之前執行過的語句完全相同,Oracle就能很快獲得已經被解析的語句以及最好的執行方案。Oracle的這個功能大大地提高了SQL的執行性能并節省了內存的使用。
可惜的是,Oracle只對簡單的表提供高速緩沖,這個功能并不適用于多表連接查詢。數據庫管理員必須在啟動參數文件中為這個區域設置合適的參數,當這個內存區域越大,就可以保留更多的語句,當然被共享的可能性也就越大了。當向Oracle提交一個SQL語句時,Oracle會首先在這塊內存中查找相同的語句。
要使用內存中共享池的SQL,必須滿足以下條件:當前被執行的語句和共享池中的語句必須完全相同 (包括大小寫、空格、換行等),兩個語句所指的對象必須完全相同 (同義詞與表是不同的對象);兩個SQL語句中必須使用相同的名字的綁定變量。Oracle對兩者采取的是一種嚴格匹配策略。
能夠使用共享的語句必須滿足三個條件:
(1)前被執行的語句和共享池中的語句必須完全相同 (包括大小寫、空格、換行等)。
(2)兩個語句所指的對象必須完全相同 (同義詞與表是不同的對象),即兩條SQL語句操作的數據庫對象必須相同。
(3)語句中必須使用相同命名的綁定變量。如:第一組的兩個SQL語句是相同的,可以共享;而第二組中兩個語句不同,即使在運行時賦予不同的綁定變量以相同的值:
【例14-1】寫兩組綁定變量的語句,分析是否可以共享。
第一組代碼如下:
select pin,name from people where pin = :blk1.pin;
select pin,name from people where pin =:blk1.pin;
由于語句完全相同,所以第一組的兩個SQL語句是相同的,可以使用共享。
第二組代碼如下:
select pin,name from people where pin =:blk1.ot_jnd;
select pin,name from people where pin = :blk1.ov_jnd;
由于綁定變量名稱不同, 不可以使用共享。
第二組語句每執行一次就需要在SHARE POOL 硬解析一次,一百萬用戶就是一百萬次,消耗CPU和內存,如果業務量大,很可能導致宕庫。如果綁定變量,則只需要硬解析一次,重復調用即可。
硬解析是指Oracle在執行目標SQL時,在庫緩存中找不到可以重用的解析樹和執行計劃,而不得不從頭開始解析目標SQL并生成相應的父游標和子游標(Child Cursor)的過程。硬解析,生成執行計劃需要耗用CPU資源,以及SGA資源。
硬解析過程:
語法、語義及權限檢查;
查詢轉換(通過應用各種不同的轉換技巧,會生成語義上等同的新的SQL語句,如count會轉為count(*));
根據統計信息生成執行計劃(找出成本最低的路徑,這一步比較耗時);
將游標信息(執行計劃)保存到庫緩存。
總結:盡可能的避免硬解析,因為硬解析需要更多的CPU資源,閂等。
盡可能的使用綁定變量來避免硬解析。
cursor_sharing參數應權衡利弊,需要考慮使用similar與force帶來的影響。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/904616.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/904616.shtml
英文地址,請注明出處:http://en.pswp.cn/news/904616.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

pm2 list查詢服務時如何通過name或者namespace進行區分

在 PM2 中,如果 pm2 list 顯示的所有服務名稱(name)相同,就無法直觀地區分不同的進程。這時可以通過 --namespace(命名空間) 或 自定義 name 來區分服務。以下是解決方案: 方法 1:啟…

[python] 函數基礎

二 函數參數 2.1 必備參數(位置參數) 含義: 傳遞和定義參數的順序及個數必須一致 格式: def func(a,b) def func_1(id,passwd):print("id ",id)print("passwd ",passwd) func_1(10086,123456) 2.2 默認參數 函數: 為函數的參數提供一個默認值,如果調…

超大規模SoC后仿真流程與優化

在超大規模SoC設計中,是否需要進行全芯片后仿真(Full-Chip Post-layout Simulation)取決于多個因素,包括設計復雜度、項目風險、資源限制以及驗證目標。以下是針對這一問題的系統性分析: 1. 全芯片后仿真的必要性 需要全芯片后仿真的場景 系統級交互驗證: 跨模塊信號交互…

深入理解 Docker 網絡原理:構建高效、靈活的容器網絡

在現代軟件開發中,Docker 已經成為了容器化技術的代名詞,廣泛應用于開發、測試和生產環境。Docker 使得開發者能夠將應用及其依賴打包成一個輕量級的容器,并通過 Docker 容器化技術來實現高效的部署與管理。 然而,在日常使用 Dock…

leetcode 242. Valid Anagram

題目描述 因為s和t僅僅包含小寫字母,所以可以開一個26個元素的數組用來做哈希表。不過如果是unicode字符,那就用編程語言自帶的哈希表。 class Solution { public:bool isAnagram(string s, string t) {int n s.size();if(s.size() ! t.size())return …

4、反應釜壓力監控系統 - /自動化與控制組件/reaction-vessel-monitor

76個工業組件庫示例匯總 反應釜壓力監控組件 這是一個用于反應釜壓力監控的自定義組件,專為化工廠反應釜壓力監控設計。采用蘋果工業風格界面,簡潔優雅,功能實用,易于使用。 功能特點 實時壓力可視化:直觀展示反應…

系統思考助力富維東陽

剛剛完成了長春一家汽車零配件公司關于系統思考的項目! 在開班儀式上,公司總經理深刻闡述了項目的背后意義,強調了系統思考與公司戰略的緊密聯系。這不僅是一次培訓,更是一次關于“如何全方位看待問題”的深度對話。 在這個過程中…

Linux下的c/c++開發之操作Sqlite3數據庫

libsqlite3-dev 介紹(Linux 下的 SQLite3 C/C 開發包) libsqlite3-dev 是一個開發包,在 Linux 環境下為使用 SQLite3 C API 進行開發的 C/C 程序員提供頭文件(如 sqlite3.h)和靜態庫/動態庫的鏈接信息(如 …

【Prompt工程—文生圖】案例大全

目錄 一、人物繪圖 二、卡通頭像 三、風景圖 四、logo設計圖 五、動物形象圖 六、室內設計圖 七、動漫風格 八、二次元圖 九、日常場景圖 十、古風神化圖 十一、游戲場景圖 十二、電影大片質感 本文主要介紹了12種不同類型的文生圖技巧,通過加入不同的圖像…

GMRES算法處理多個右端項的Block與PseudoBlock變體

GMRES算法處理多個右端項的Block與PseudoBlock變體 Block與PseudoBlock GMRES簡介 在處理多個右端項的線性方程組時,Block GMRES和PseudoBlock GMRES是兩種常用的變體算法: Block GMRES:同時處理所有右端項,構建一個大的Krylov…

Ubuntu環境下如何管理系統中的用戶:創建用戶、刪除用戶、修改密碼、切換用戶、用戶組管理

管理用戶的操作需要root權限,在執行命令時需要加sudo,關于sudo命令可以看這篇:Linux_sudo命令的使用與機制 1、添加用戶 使用命令: adduser 用戶名,主要是按提示輸入密碼和用戶信息(可直接回車使用默認配置…

開源BI選型及DataEase搭建

工具名稱 國家/社區技術棧核心功能國內適用性國外適用性推薦場景Apache Superset美國(Apache)Python/React可視化、SQL Lab、多數據源、插件擴展需自行漢化,社區支持較少生態完善,云原生支持好(AWS/GCP)中大…

云計算-容器云-部署jumpserver 版本1

部署jumpserver [root@jumpserver ~]# tar -zxvf jumpserver.tar.gz -C /opt/ [root@jumpserver ~]# ls /opt/ compose config docker docker.service images jumpserver-repo static.env將默認Yum源移至其他目錄,創建本地Yum源文件,命令及文件內容如下: [root@jumpserver…

利用Elixir中的原子特性 + 錯誤消息泄露 -- Atom Bomb

題目信息: This new atom bomb early warning system is quite strange… 題目使用 elixir 語言 一開始,我們會訪問 /page.html <!DOCTYPE html> <!-- 設定文檔語言為英語 --> <html lang"en"> <head><!-- 設定字符編碼為UTF-8 --><…

Spring MVC設計與實現

DispatcherServlet的初始化與請求處理流程 初始化階段 Servlet 生命周期觸發&#xff1a;當 Web 容器&#xff08;如 Tomcat&#xff09;啟動時&#xff0c;根據注解/配置&#xff0c;DispatcherServlet 的 init() 方法被調用。 初始化 WebApplicationContext 根 WebApplicat…

64.微服務保姆教程 (七) RocketMQ--分布式消息中間件

RocketMQ–分布式消息中間件 一、MQ 1、什么是MQ MQ(Message Queue)消息隊列,是基礎數據結構中“先進先出”的一種數據結構。指把要傳輸的數據(消息)放在隊列中,用隊列機制來實現消息傳遞——生產者產生消息并把消息放入隊列,然后由消費者去處理。消費者可以到指定隊…

java算法的核心思想及考察的解題思路

一、Java算法的核心思想 1. 分而治之 (Divide and Conquer) 將大問題分解為小問題&#xff0c;遞歸解決小問題后合并結果 典型應用&#xff1a;歸并排序、快速排序、二分查找 2. 動態規劃 (Dynamic Programming) 將問題分解為重疊子問題&#xff0c;存儲子問題的解避免重復…

linux查java進程CPU高的原因

問題&#xff1a;linux查java進程CPU高的原因 解決&#xff1a;用jdk帶的工具分析 被查的java最好也使用jdk啟動 systemctl啟動的注意要去掉PrivateTmptrue /opt/jdk1.8.0_441/bin/jps -l top -Hp 8156 printf "%x" 8533 /opt/jdk1.8.0_441/bin/jstack 8156 |…

體育培訓的實驗室管理痛點 質檢LIMS如何重構體育檢測價值鏈

在競技體育與全民健身并行的時代背景下&#xff0c;體育培訓機構正面臨雙重挑戰&#xff1a;既要通過科學訓練提升學員競技水平&#xff0c;又需嚴格把控運動安全風險。作為實驗室數字化管理的核心工具&#xff0c;質檢LIMS系統憑借其標準化流程管控與智能化數據分析能力&#…

linux下MySql的安裝與配置

一鍵三聯&#xff0c;把mysql的安裝與配置也寫了&#xff0c;供各位參考。 --------------------------------------MySql的安裝與配置-------------------------------------- 1 將下載的 壓縮包解壓到指定目錄 tar -zxvf mysql-5.7.26-linux-glibc2.12-x86_64.tar.gz 卸載…