oracle execute immediate执行多条语句_用数据库的方式思考SQL是如何执行的
私信我或關注微信號:猿來如此呀,回復:學習,獲取免費學習資源包。
今天我們就從數據庫的角度來思考一下 SQL 是如何被執行的。
關于今天的內容,你會從以下幾個方面進行學習:
Oracle 中的 SQL 是如何執行的
我們先來看下 SQL 在 Oracle 中的執行過程:
從上面這張圖中可以看出,SQL 語句在 Oracle 中經歷了以下的幾個步驟。
在共享池中,Oracle 首先對 SQL 語句進行 Hash 運算,然后根據 Hash 值在庫緩存(Library Cache)中查找,如果存在 SQL 語句的執行計劃,就直接拿來執行,直接進入“執行器”的環節,這就是軟解析。
如果沒有找到 SQL 語句和執行計劃,Oracle 就需要創建解析樹進行解析,生成執行計劃,進入“優化器”這個步驟,這就是硬解析。
共享池是 Oracle 中的術語,包括了庫緩存,數據字典緩沖區等。我們上面已經講到了庫緩存區,它主要緩存 SQL 語句和執行計劃。而數據字典緩沖區存儲的是 Oracle 中的對象定義,比如表、視圖、索引等對象。當對 SQL 語句進行解析的時候,如果需要相關的數據,會從數據字典緩沖區中提取。
庫緩存這一個步驟,決定了 SQL 語句是否需要進行硬解析。為了提升 SQL 的執行效率,我們應該盡量避免硬解析,因為在 SQL 的執行過程中,創建解析樹,生成執行計劃是很消耗資源的。
你可能會問,如何避免硬解析,盡量使用軟解析呢?在 Oracle 中,綁定變量是它的一大特色。綁定變量就是在 SQL 語句中使用變量,通過不同的變量取值來改變 SQL 的執行結果。這樣做的好處是能提升軟解析的可能性,不足之處在于可能會導致生成的執行計劃不夠優化,因此是否需要綁定變量還需要視情況而定。
舉個例子,我們可以使用下面的查詢語句:
SQL> select * from player where player_id = 10001;
你也可以使用綁定變量,如:
SQL> select * from player where player_id = :player_id;
這兩個查詢語句的效率在 Oracle 中是完全不同的。如果你在查詢 player_id = 10001 之后,還會查詢 10002、10003 之類的數據,那么每一次查詢都會創建一個新的查詢解析。而第二種方式使用了綁定變量,那么在第一次查詢之后,在共享池中就會存在這類查詢的執行計劃,也就是軟解析。
因此我們可以通過使用綁定變量來減少硬解析,減少 Oracle 的解析工作量。但是這種方式也有缺點,使用動態 SQL 的方式,因為參數不同,會導致 SQL 的執行效率不同,同時 SQL 優化也會比較困難。
MySQL 中的 SQL 是如何執行的
Oracle 中采用了共享池來判斷 SQL 語句是否存在緩存和執行計劃,通過這一步驟我們可以知道應該采用硬解析還是軟解析。那么在 MySQL 中,SQL 是如何被執行的呢?
首先 MySQL 是典型的 C/S 架構,即 Client/Server 架構,服務器端程序使用的 mysqld。整體的 MySQL 流程如下圖所示:
你能看到 MySQL 由三層組成:
其中 SQL 層與數據庫文件的存儲方式無關,我們來看下 SQL 層的結構:
你能看到 SQL 語句在 MySQL 中的流程是:SQL 語句→緩存查詢→解析器→優化器→執行器。在一部分中,MySQL 和 Oracle 執行 SQL 的原理是一樣的。
與 Oracle 不同的是,MySQL 的存儲引擎采用了插件的形式,每個存儲引擎都面向一種特定的數據庫應用環境。同時開源的 MySQL 還允許開發人員設置自己的存儲引擎,下面是一些常見的存儲引擎:
需要注意的是,數據庫的設計在于表的設計,而在 MySQL 中每個表的設計都可以采用不同的存儲引擎,我們可以根據實際的數據處理需要來選擇存儲引擎,這也是 MySQL 的強大之處。
數據庫管理系統也是一種軟件
我們剛才了解了 SQL 語句在 Oracle 和 MySQL 中的執行流程,實際上完整的 Oracle 和 MySQL 結構圖要復雜得多:
如果你只是簡單地把 MySQL 和 Oracle 看成數據庫管理系統軟件,從外部看難免會覺得“晦澀難懂”,畢竟組織結構太多了。我們在學習的時候,還需要具備抽象的能力,抓取最核心的部分:SQL 的執行原理。因為不同的 DBMS 的 SQL 的執行原理是相通的,只是在不同的軟件中,各有各的實現路徑。
既然一條 SQL 語句會經歷不同的模塊,那我們就來看下,在不同的模塊中,SQL 執行所使用的資源(時間)是怎樣的。下面我來教你如何在 MySQL 中對一條 SQL 語句的執行時間進行分析。
首先我們需要看下 profiling 是否開啟,開啟它可以讓 MySQL 收集在 SQL 執行時所使用的資源情況,命令如下:
mysql> select @@profiling;
profiling=0 代表關閉,我們需要把 profiling 打開,即設置為 1:
mysql> set profiling=1;
然后我們執行一個 SQL 查詢(你可以執行任何一個 SQL 查詢):
mysql> select * from wucai.heros;
查看當前會話所產生的所有 profiles,你會發現我們剛才執行了兩次查詢,Query ID 分別為 1 和 2。如果我們想要獲取上一次查詢的執行時間,可以使用:
mysql> show profile;
當然你也可以查詢指定的 Query ID,比如:
mysql> show profile for query 2;
查詢 SQL 的執行時間結果和上面是一樣的。
在 8.0 版本之后,MySQL 不再支持緩存的查詢,原因我在上文已經說過。一旦數據表有更新,緩存都將清空,因此只有數據表是靜態的時候,或者數據表很少發生變化時,使用緩存查詢才有價值,否則如果數據表經常更新,反而增加了 SQL 的查詢時間。
你可以使用 select version() 來查看 MySQL 的版本情況。
總結
我們在使用 SQL 的時候,往往只見樹木,不見森林,不會注意到它在各種數據庫軟件中是如何執行的,今天我們從全貌的角度來理解這個問題。你能看到不同的 RDBMS 之間有相同的地方,也有不同的地方。
相同的地方在于 Oracle 和 MySQL 都是通過解析器→優化器→執行器這樣的流程來執行 SQL 的。
但 Oracle 和 MySQL 在進行 SQL 的查詢上面有軟件實現層面的差異。Oracle 提出了共享池的概念,通過共享池來判斷是進行軟解析,還是硬解析。而在 MySQL 中,8.0 以后的版本不再支持查詢緩存,而是直接執行解析器→優化器→執行器的流程,這一點從 MySQL 中的 show profile 里也能看到。同時 MySQL 的一大特色就是提供了各種存儲引擎以供選擇,不同的存儲引擎有各自的使用場景,我們可以針對每張表選擇適合的存儲引擎。
今天的內容到這里就結束了,你能說一下 Oracle 中的綁定變量是什么嗎?使用它有什么優缺點嗎?MySQL 的存儲引擎是一大特色,其中 MyISAM 和 InnoDB 都是常用的存儲引擎,這兩個搜索引擎的特性和使用場景分別是什么?
最后留一道選擇題吧,解析后的 SQL 語句在 Oracle 的哪個區域中進行緩存?
A. 數據緩沖區
B. 日志緩沖區
C. 共享池
D. 大池
如果這篇文章幫你理順了 Oracle 和 MySQL 執行 SQL 的過程,歡迎你把它分享給你的朋友或者同事。
來源網絡,侵權聯系刪除
總結
以上是生活随笔為你收集整理的oracle execute immediate执行多条语句_用数据库的方式思考SQL是如何执行的的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 我国首个“风光火储一体化”送电特高压工程
- 下一篇: 360发布年度手机安全报告:受骗男性占七