Oracle查看執(zhí)行計劃的實現(xiàn)
一、什么是執(zhí)行計劃?
執(zhí)行計劃是由Oracle數(shù)據(jù)庫系統(tǒng)生成的,它描述了SQL語句的執(zhí)行方式,包括SQL語句的執(zhí)行順序、使用的索引、表之間的連接方式等等。執(zhí)行計劃可以通過多種方式獲取,如使用EXPLAIN PLAN語句、使用SQL Trace功能、使用SQL Developer等工具。
二、執(zhí)行計劃的目的
查看 Oracle 的執(zhí)行計劃的目的是為了了解 SQL 查詢或語句在數(shù)據(jù)庫中的執(zhí)行方式和性能表現(xiàn)。執(zhí)行計劃是一個詳細的指南,它描述了 Oracle 數(shù)據(jù)庫是如何執(zhí)行查詢的,包括使用哪些索引、連接順序、使用何種算法等等。
通過查看執(zhí)行計劃,可以識別出潛在的性能問題或優(yōu)化機會。執(zhí)行計劃提供了查詢優(yōu)化器在決定如何執(zhí)行查詢時所做的選擇的信息,可以幫助開發(fā)人員或數(shù)據(jù)庫管理員了解查詢的成本和效率,并根據(jù)需要進行調(diào)整和優(yōu)化。
執(zhí)行計劃可以揭示查詢中存在的性能瓶頸、慢查詢或未充分利用索引的情況。它還可以幫助開發(fā)人員理解查詢的執(zhí)行順序,以及可能引起性能下降的地方。通過分析執(zhí)行計劃,可以確定是否需要調(diào)整查詢、添加索引、重寫查詢邏輯或優(yōu)化數(shù)據(jù)庫結(jié)構(gòu),以提高查詢性能和響應(yīng)時間。
總結(jié)為以下幾點:
- 1. 了解SQL語句的執(zhí)行方式,幫助開發(fā)人員和DBA分析SQL語句的性能瓶頸。
- 2. 查看SQL語句的執(zhí)行效率,幫助開發(fā)人員和DBA優(yōu)化SQL語句的性能。
- 3. 了解數(shù)據(jù)庫的物理結(jié)構(gòu),如索引、表之間的連接方式等。
- 4. 幫助開發(fā)人員和DBA了解Oracle數(shù)據(jù)庫的執(zhí)行策略,以便于更好地進行數(shù)據(jù)庫設(shè)計和優(yōu)化。
三、獲取執(zhí)行計劃信息
查詢 Oracle 的執(zhí)行計劃可以提供以下信息:
3.1訪問路徑(Access Path):
執(zhí)行計劃顯示了查詢?nèi)绾卧L問表或索引,包括全表掃描、索引掃描、索引范圍掃描等。這可以幫助確定數(shù)據(jù)是如何被檢索的。
3.2連接順序(Join Order):
如果查詢涉及多個表的連接操作,執(zhí)行計劃將顯示連接的順序。這對于優(yōu)化查詢的性能很重要,因為不同的連接順序可能會導致不同的性能。
3.3連接類型(Join Type):
執(zhí)行計劃指示了連接操作使用的連接類型,如內(nèi)連接、外連接或半連接。這對于了解查詢中不同連接操作的性能影響很有幫助。
3.4過濾條件(Filter Predicates):
執(zhí)行計劃會顯示應(yīng)用在表或索引訪問上的過濾條件。這可以幫助確認查詢中的過濾邏輯是否被正確地應(yīng)用。
3.5排序操作(Sort Operations):
如果查詢涉及排序操作,執(zhí)行計劃將顯示排序的方式和排序所使用的算法。這對于優(yōu)化排序操作的性能很有幫助。
3.6聚合操作(Aggregation Operations):
如果查詢包含聚合函數(shù)(如 SUM、AVG、COUNT 等),執(zhí)行計劃將顯示聚合操作的方式和執(zhí)行方法。
3.7數(shù)據(jù)庫統(tǒng)計信息(Statistics):
執(zhí)行計劃可以提供表、索引或列的統(tǒng)計信息,如行數(shù)、唯一值數(shù)量等。這對于優(yōu)化查詢計劃選擇和索引設(shè)計很重要。
通過分析執(zhí)行計劃,可以確定查詢中的性能瓶頸和優(yōu)化機會,了解查詢的執(zhí)行方式,以及根據(jù)需要進行調(diào)整和優(yōu)化的方法。
四、執(zhí)行計劃的執(zhí)行順序
Oracle執(zhí)行計劃的執(zhí)行順序是從上往下,從右往左。也就是說,執(zhí)行計劃的最底部是最后執(zhí)行的操作,而最頂部是最先執(zhí)行的操作。左邊的操作優(yōu)先級低于右邊的操作,也就是說,右邊的操作先執(zhí)行,左邊的操作后執(zhí)行。
口訣:
- 縮進最深的,最先執(zhí)行
- 縮進深度相同的,先上后下
五、執(zhí)行計劃的存儲區(qū)
主要包括以下幾個部分:
- 1. 表操作符:表示對表的操作,如全表掃描、索引掃描等。
- 2. 連接操作符:表示對表之間的連接操作,如HASH JOIN、NESTED LOOPS JOIN等。
- 3. 過濾操作符:表示對結(jié)果集進行過濾的操作,如WHERE、HAVING等。
- 4. 訪問操作符:表示對數(shù)據(jù)的訪問操作,如INDEX、TABLE等。
- 5. 排序操作符:表示對結(jié)果集進行排序的操作,如ORDER BY、GROUP BY等。
- 6. 其他操作符:表示其他類型的操作符,如UNION、INTERSECT等。
執(zhí)行計劃中的每個操作符都有對應(yīng)的存儲區(qū),用于存儲該操作符的執(zhí)行結(jié)果。執(zhí)行計劃中的每個操作符都有自己的任務(wù)和目的,它們通過組合形成完整的SQL語句執(zhí)行計劃,最終實現(xiàn)對數(shù)據(jù)的查詢和操作。
六、執(zhí)行計劃的執(zhí)行步驟
- 1. SQL解析:將SQL語句進行語法解析,確定語句的語義和結(jié)構(gòu)。
- 2. 查詢優(yōu)化:優(yōu)化器根據(jù)SQL語句和數(shù)據(jù)庫的統(tǒng)計信息,選擇最優(yōu)的執(zhí)行計劃。
- 3. 執(zhí)行計劃生成:根據(jù)查詢優(yōu)化產(chǎn)生的最優(yōu)執(zhí)行計劃,生成執(zhí)行計劃樹。
- 4. 執(zhí)行計劃執(zhí)行:按照執(zhí)行計劃樹的順序,執(zhí)行各個操作步驟,包括表掃描、索引掃描、排序、聚合等。
- 5. 結(jié)果返回:將執(zhí)行結(jié)果返回給客戶端。
- 6. 監(jiān)控和調(diào)優(yōu):根據(jù)執(zhí)行計劃的執(zhí)行情況,對性能進行監(jiān)控和調(diào)優(yōu),如調(diào)整參數(shù)、優(yōu)化SQL語句等。
七、執(zhí)行計劃中各字段的描述
7.1、基本字段(總是可用的)
- Id 執(zhí)行計劃中每一個操作(行)的標識符。如果數(shù)字前面帶有星號,意味著將在隨后提供這行包含的謂詞信息
- Operation 對應(yīng)執(zhí)行的操作。也叫行源操作
- Name 操作的對象名稱
7.2、查詢優(yōu)化器評估信息
- Rows(E-Rows) 預估操作返回的記錄條數(shù)
- Bytes(E-Bytes) 預估操作返回的記錄字節(jié)數(shù)
- TempSpc 預估操作使用臨時表空間的大小
- Cost(%CPU) 預估操作所需的開銷。在括號中列出了CPU開銷的百分比。注意這些值是通過執(zhí)行計劃計算出來的。
換句話說,父操作的開銷包含子操作的開銷
- Time 預估執(zhí)行操作所需要的時間(HH:MM:SS)
7.3、分區(qū)(僅當訪問分區(qū)表時下列字段可見)
- Pstart 訪問的第一個分區(qū)。如果解析時不知道是哪個分區(qū)就設(shè)為 KEY,KEY(I),KEY(MC),KEY(OR),KEY(SQ)
- Pstop 訪問的最后一個分區(qū)。如果解析時不知道是哪個分區(qū)就設(shè)為KEY,KEY(I),KEY(MC),KEY(OR),KEY(SQ)
7.4、并行和分布式處理(僅當使用并行或分布式操作時下列字段可見)
- Inst 在分布式操作中,指操作使用的數(shù)據(jù)庫鏈接的名字
- TQ 在并行操作中,用于從屬線程間通信的表隊列
- IN-OUT 并行或分布式操作間的關(guān)系
- PQ Distrib 在并行操作中,生產(chǎn)者為發(fā)送數(shù)據(jù)給消費者進行的分配
7.5、運行時統(tǒng)計(當設(shè)定參數(shù)statistics_level為all或使用gather_plan_statistics提示時,下列字段可見)
- Starts 指定操作執(zhí)行的次數(shù)
- A-Rows 操作返回的真實記錄數(shù)
- A-Time 操作執(zhí)行的真實時間(HH:MM:SS.FF)
7.6、I/O 統(tǒng)計(當設(shè)定參數(shù)statistics_level為all或使用gather_plan_statistics提示時,下列字段可見)
- Buffers 執(zhí)行期間進行的邏輯讀操作數(shù)量
- Reads 執(zhí)行期間進行的物理讀操作數(shù)量
- Writes 執(zhí)行期間進行的物理寫操作數(shù)量
7.7、內(nèi)存使用統(tǒng)計
- OMem 最優(yōu)執(zhí)行所需內(nèi)存的預估值
- 1Mem 一次通過(one-pass)執(zhí)行所需內(nèi)存的預估值
- 0/1/M 最優(yōu)/一次通過/多次通過(multipass)模式操作執(zhí)行的次數(shù)
- Used-Mem 最后一次執(zhí)行時操作使用的內(nèi)存量
- Used-Tmp 最后一次執(zhí)行時操作使用的臨時空間大小。這個字段必須擴大1024倍才能和其他衡量內(nèi)存的字段一致(比如,32k意味著32MB)
- Max-Tmp 操作使用的最大臨時空間大小。這個字段必須擴大1024倍才能和其他衡量內(nèi)存的字段一致(比如,32k意味著32MB)
八、查看執(zhí)行計劃語法
在Oracle數(shù)據(jù)庫中,可以通過使用“EXPLAIN PLAN”命令來查看查詢語句的執(zhí)行計劃。下面是詳細的使用方法及實例說明:
8.1. 基本語法
EXPLAIN PLAN FOR SELECT * FROM table_name WHERE condition;
8.2. 查看執(zhí)行計劃
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
九、實例說明
假設(shè)我們有一個表“employees”,包含員工的基本信息,我們要查詢薪水大于5000的員工信息。我們可以使用以下命令來查看查詢語句的執(zhí)行計劃:
EXPLAIN PLAN FOR SELECT * FROM employees WHERE salary > 5000;
執(zhí)行上述命令后,可以通過以下命令來查看執(zhí)行計劃:
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
查詢結(jié)果中會顯示查詢語句的執(zhí)行計劃,包括每個操作的類型、所涉及的表或索引、所需的成本等信息。例如,查詢結(jié)果可能如下所示:
備注(不用上滑了,納多費勁呀,我懂你累?。。?/strong>
- 1. ID:查詢語句中每個操作的唯一標識符,可以通過ID來查看操作之間的關(guān)系。
- 2. Operation:查詢語句中每個操作的類型,例如Full Table Scan、Index Scan等。
- 3. Name:表示操作所涉及的表或索引的名稱。
- 4. Rows:表示操作所涉及的行數(shù)或估計的行數(shù)。
- 5. Bytes:表示操作所涉及的字節(jié)數(shù)或估計的字節(jié)數(shù)。
- 6. Cost:表示操作所需的成本,包括CPU成本和I/O成本。
- 7.Time:表示操作所需的時間。
解釋:
Full Table Scan 和 Index Scan 都是一種查詢表數(shù)據(jù)的方式。
Full Table Scan 是一種全表掃描的方法,即當我們的查詢條件不能使用索引進行查找時,Oracle就會對整個包含了表數(shù)據(jù)的數(shù)據(jù)塊進行掃描,從而獲取需要的數(shù)據(jù)。
Index Scan(也被稱為Index Range Scan)則利用了表上的索引,查詢時只掃描符合指定范圍條件的索引結(jié)構(gòu),從而快速定位到匹配的記錄。如果查詢條件可以使用索引,則選擇Index Scan 可以大大提高查詢性能。
總結(jié):Full Table Scan 通常發(fā)生在沒有使用索引或索引不能完全匹配查詢條件的情況下,數(shù)據(jù)查詢速度相對較慢;Index Scan 則利用索引有序性,可快速定位滿足查詢條件的數(shù)據(jù)行,并且查詢速度更快。
分析以上結(jié)果:
①ID為0的操作為SELECT STATEMENT,表示整個查詢語句的執(zhí)行計劃;
②ID為1的操作為TABLE ACCESS FULL,表示對表“employees”進行全表掃描。
③Predicate Information (identified by operation id) 表示操作所用到的謂詞信息,其中 operation id 表示當前操作的 ID 號,謂詞信息包括過濾條件、連接條件等。
Predicate Information 中的謂詞信息對于理解 SQL 查詢的執(zhí)行計劃非常重要。它告訴我們查詢優(yōu)化器是如何使用索引、過濾條件等對數(shù)據(jù)進行篩選和連接的。通過分析 Predicate Information,可以發(fā)現(xiàn) SQL 查詢中的性能瓶頸,從而進行優(yōu)化。
例如:
- 如果 Predicate Information 中顯示的是 Index (range scan) 則表示查詢優(yōu)化器使用了索引進行范圍掃描。
- 如果 Predicate Information 中顯示的是 Filter,則表示查詢優(yōu)化器使用了過濾條件來篩選數(shù)據(jù)。
- 如果 Predicate Information 中顯示的是 Join,則表示查詢優(yōu)化器使用了連接條件來連接多個表。
④1 - filter("SALARY">5000) 表示當前操作是對表進行過濾操作,過濾條件為 "SALARY">5000,即薪資大于 5000 的記錄。
這個操作通常出現(xiàn)在 SELECT 語句中,用于篩選符合條件的記錄。在執(zhí)行計劃中,這個操作通常出現(xiàn)在表掃描、索引掃描等操作之后,用于進一步篩選數(shù)據(jù)。
在執(zhí)行計劃中,filter 操作的代價通常比較小,因為它只是對已經(jīng)掃描的記錄進行進一步篩選,而不需要進行額外的磁盤 IO 操作。但是,如果 filter 操作出現(xiàn)在操作樹的頂部,代價可能會比較大,因為它需要讀取整個表或索引,并將不符合條件的記錄過濾掉。
在 SQL 查詢的優(yōu)化過程中,通常要盡量減少 filter 操作的出現(xiàn),可以通過添加索引、修改查詢條件等方式來避免 filter 操作的出現(xiàn)。
我們可以通過這些信息來了解查詢語句的執(zhí)行計劃及其效率,從而進行優(yōu)化。
十、PLSQL Developer中的F5
依舊是查詢表“employees”薪水大于5000的員工信息,我們可以使用快捷鍵F5來查看查詢語句的執(zhí)行計劃,如下圖所示:
通過切換不同的展示格式,我們可以看到各種信息,但是展示結(jié)果與使用explain plan for語句是一樣的,這種方式可以更加的快捷方便!
上面的例子相對來說展示結(jié)果比較單一,接下來舉用下面的例子再描述以下,已知員工表employees和部門表departments,現(xiàn)要求查詢出員工薪資為6000的員工信息和部門信息,我們可以用快捷鍵F5查看下他的執(zhí)行計劃:
①在上途中我們發(fā)現(xiàn)TABLE ACCESS FULL 時,通常意味著該查詢使用了 Full Table Scan 的方式來訪問表。上面有提到了這個方式,但我還是要再嘮叨一下:
Full Table Scan 是一種全表掃描的方法,即當我們的查詢條件不能使用索引進行查找時,Oracle就會對整個包含了表數(shù)據(jù)的數(shù)據(jù)塊進行掃描,從而獲取需要的數(shù)據(jù)。此時, Oracle 就會選擇使用 TABLE ACCESS FULL 操作符。
如果查詢中使用了 TABLE ACCESS FULL 而沒有使用索引,則可能導致查詢速度相對較慢,對于較大的表來說,這種方法可能會產(chǎn)生很高的 I/O 成本和 CPU 成本,不利于系統(tǒng)性能。
注意:
在實際應(yīng)用中,盡可能避免使用 Full Table Scan,可以考慮使用合適的索引或優(yōu)化查詢語句等方式提高查詢性能。
②在執(zhí)行計劃中,還發(fā)現(xiàn)了INDEX UNIQUE SCAN ,它表示對于一個唯一索引或主鍵索引的范圍查找方式。
當查詢語句中包含了對唯一索引或主鍵索引字段的等值(=)條件時,在執(zhí)行計劃中就會顯示 Index Unique Scan 操作。這種方法可以非??焖俚囟ㄎ坏叫枰樵兊男校⑶也粫a(chǎn)生重復數(shù)據(jù)輸出。
與普通索引掃描不同的是,Index Unique Scan 確保查詢結(jié)果最多只有一行記錄,因為唯一索引或主鍵索引本身就定義了數(shù)據(jù)行的唯一性。因此,如果我們可以通過索引的方式找到精確匹配的數(shù)據(jù),則最好使用 INDEX UNIQUE SCAN 以提高查詢效率。
總之,Index Unique Scan 是一種高效的查詢方式,適用于對于唯一索引或主鍵索引進行查詢的場景。同時,建立合適的索引也是提高查詢性能的重要手段之一。
③在執(zhí)行計劃中,還發(fā)現(xiàn)了TABLE ACCESS BY INDEX ROWID ,它表示通過索引行 ID 進行表數(shù)據(jù)訪問的操作。一般而言,使用該操作符需要經(jīng)過以下步驟:
- 1. 根據(jù)查詢語句中的條件,找到合適的索引;
- 2. 使用索引查找所需的數(shù)據(jù)行的 Rowid;
- 3. 根據(jù) Step 2 中獲取的 Rowid 值,從表中取出對應(yīng)的數(shù)據(jù)行。
這個操作符與其他操作符最大的區(qū)別在于,它不是針對索引進行數(shù)據(jù)訪問,而是針對實際的數(shù)據(jù)表進行訪問。因此,TABLE ACCESS BY INDEX ROWID 可以通過索引快速定位到需要的數(shù)據(jù)行,并根據(jù) Rowid 直接訪問表數(shù)據(jù),從而提高查詢的效率。
注意:
在使用 TABLE ACCESS BY INDEX ROWID 時,如果表的數(shù)據(jù)分散在多個磁盤塊中,就可能會產(chǎn)生很高的 I/O 成本和 CPU 成本,導致查詢性能下降。因此,在進行優(yōu)化時,應(yīng)盡量避免物理磁盤 IO 操作的數(shù)量,可以通過內(nèi)存或者調(diào)整磁盤布局等方式來改善性能。
④在本文章的第四節(jié)【四、執(zhí)行計劃的執(zhí)行順序】提到了執(zhí)行順序,那么我們在上圖的樹結(jié)構(gòu)--耗費就可以知道他們的執(zhí)行順序是怎樣排序的,如果不清楚,我們九可以點擊圖中標記的三角提示進行查看。
通過HTML框圖我們可以清楚知道索引掃描的索引名字,全表掃描的表名,分別掃描了多少行,預估多少個字節(jié),CPU的消耗和操作執(zhí)行消耗的時間等信息。
文本圖的展示與explain plan for語句執(zhí)行結(jié)果大致一樣,不再過多描述。
上面也有展示了此圖,大家一定很好奇它是干什么的,哈哈哈?。?!不急,下面給你簡單描述一下情況!
在 Oracle SQL Developer 中,使用快捷鍵 F5 可以查看 SQL 語句的執(zhí)行計劃。這個操作會打開一個新窗口,展示查詢 SQL 的執(zhí)行計劃圖表與一些統(tǒng)計信息。
如果我們在執(zhí)行計劃窗口中選擇了“Explain Plan(XML Format)”,那么窗口下方將會展示該查詢語句的 XML 執(zhí)行計劃,其中包括了多個執(zhí)行計劃步驟及其相應(yīng)的輸入、輸出參數(shù)和所涉及的對象等信息。
Oracle 數(shù)據(jù)庫管理系統(tǒng)使用 XML 格式來表示執(zhí)行計劃,這種格式的優(yōu)點是可讀性好,易于在不同平臺之間進行傳輸和共享。通過查看 XML 執(zhí)行計劃,我們可以更深入地了解查詢的執(zhí)行細節(jié),幫助我們分析和優(yōu)化查詢性能問題。
到此這篇關(guān)于Oracle查看執(zhí)行計劃的實現(xiàn)的文章就介紹到這了,更多相關(guān)Oracle查看執(zhí)行計劃內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
講解Oracle數(shù)據(jù)庫中的數(shù)據(jù)字典及相關(guān)SQL查詢用法
這篇文章主要介紹了Oracle數(shù)據(jù)庫中的數(shù)據(jù)字典及相關(guān)SQL查詢用法,是Oracle入門學習中的基礎(chǔ)知識,需要的朋友可以參考下2016-03-03oracle 監(jiān)聽 lsnrctl 命令 (推薦)
這篇文章主要介紹了oracle 監(jiān)聽 lsnrctl 命令 ,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2017-03-03Oracle rac環(huán)境的數(shù)據(jù)庫導入操作步驟
Oracle RAC是一種基于共享存儲和共享數(shù)據(jù)庫的集群解決方案,可以將多個 Oracle 數(shù)據(jù)庫實例連接成一個邏輯上的單一數(shù)據(jù)庫,提供高可用性、靈活性和可伸縮性,本文給大家介紹Oracle rac環(huán)境的數(shù)據(jù)庫導入操作,感興趣的朋友一起看看吧2023-06-06安裝Oracle加載數(shù)據(jù)庫錯誤areasQueries的解決
安裝Oracle加載數(shù)據(jù)庫錯誤areasQueries的解決...2007-03-03如何使用GDAL庫的ogr2ogr將GeoJSON數(shù)據(jù)導入到PostgreSql中
本文主要介紹了PyTorch中的masked_fill函數(shù)的基本知識和使用方法,masked_fill函數(shù)接受一個輸入張量和一個布爾掩碼作為主要參數(shù),掩碼的形狀必須與輸入張量相同,掩碼操作根據(jù)掩碼中的布爾值在輸出張量中填充指定的值或保留輸入張量中的值2024-10-10解決ORA-01747:user.table.column,table.column或列說明無效
這篇文章主要介紹了解決ORA-01747:user.table.column,table.column或列說明無效的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07Oracle數(shù)據(jù)庫兩表關(guān)聯(lián)更新的問題
需要寫一個更新語句,但是更新的判斷條件是兩個表關(guān)聯(lián)查詢出來的,本文通過實例代碼給大家講解Oracle數(shù)據(jù)庫兩表關(guān)聯(lián)更新的問題及遇到的坑,感興趣的朋友一起看看吧2023-11-11