欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Oracle查看SQL執(zhí)行計劃的幾種方法

 更新時間:2024年11月12日 10:09:58   作者:學無止境的小一  
在日常的運維工作中,SQL優(yōu)化是DBA的進階技能,SQL優(yōu)化的前提是要看SQL的執(zhí)行計劃是否正確,下面分享幾種查看執(zhí)行計劃的方法,每一種方法都各有各的好處,可以根據(jù)特定場景選擇某種方法,需要的朋友可以參考下

Oracle查看SQL執(zhí)行計劃的方法

一.使用AUTOTRACE查看執(zhí)行計劃

我們利用SQLPLUS中自帶的AUTOTRACE工具查看執(zhí)行計劃。AUTOTRACE用法如下。

set autot on:			該命令會運行SQL并且顯示運行結(jié)果,執(zhí)行計劃和統(tǒng)計信息。
set autot trace:		該命令會運行SQL,但不顯示運行結(jié)果,會顯示執(zhí)行計劃和統(tǒng)計信息。
set autot trace exp:	運行該命令查詢語句不執(zhí)行,DML語句會執(zhí)行,只顯示執(zhí)行計劃。
set autot trace stat:	該命令會運行 SQL,只顯示統(tǒng)計信息。
set autot off:			關(guān)閉 AUTOTRACE。

-執(zhí)行計劃中的各個參數(shù)解釋
recursive calls 			表示遞歸調(diào)用的次數(shù),一個SQL第一次執(zhí)行就會發(fā)生硬解析,在硬解析的時候,優(yōu)化器會隱含地調(diào)用一些內(nèi)部SQL,因此當一個SQL第一次執(zhí)行,recursive calls會大于0,第二次執(zhí)行的時候不需要遞歸調(diào)用,recursive calls就會等于0,如果SQL語句中有自定義函數(shù),recursive calls永遠不會等于0,自定義函數(shù)被調(diào)用了多少次,recursive calls就會顯示為多少次
db block gets				表示有多少塊發(fā)生變化,一般情況下只有DML語句才會導致塊發(fā)生變化,所以查詢語句中的db block gets一般為0
consistent gets				表示邏輯讀,單位是塊。在SQL優(yōu)化的時候我們應(yīng)該想方設(shè)法減少邏輯讀的個數(shù),通常情況下邏輯讀越小,性能越好。需要注意的是,邏輯讀并不是衡量SQL執(zhí)行快慢的唯一標準,需要結(jié)合I/O
physical reads				表示從磁盤讀取了多少個數(shù)據(jù)塊,也就是物理讀。如果表已經(jīng)被緩存在buffer cache中,沒有物理讀,那么會等于0
redo size					表示產(chǎn)生了多少字節(jié)的重做日志,一般也是只有DML語句會產(chǎn)生redo,查詢語句一般情況下不會產(chǎn)生redo
bytes sent via SQL*Net to client					表示從數(shù)據(jù)庫服務(wù)器發(fā)送了多少字節(jié)到客戶端
bytes received via SQL*Net from client				表示從客戶端發(fā)送了多少字節(jié)到服務(wù)端
SQL*Net roundtrips to/from client					表示客戶端與數(shù)據(jù)庫服務(wù)端交互次數(shù),我們可以通過設(shè)置arraysize減少交互次數(shù)
sorts (memory)				內(nèi)存排序的次數(shù)
sorts (disk)				磁盤排序的次數(shù)
rows processed				表示SQL一共返回多少行數(shù)據(jù)。我們在做SQL優(yōu)化的時候最關(guān)心這部分數(shù)據(jù),因為可以根據(jù)SQL返回的行數(shù)判斷整個SQL應(yīng)該是走HASH連接還是走嵌套循環(huán)。如果rows processed很大,一般走HASH連接,如果rows processed很小,一般走嵌套循環(huán)。

二.使用EXPLAIN PLAN FOR查看執(zhí)行計劃

用法如下

explain plan for SQL語句;
select * from table(dbms_xplan.display);

-查看高級(ADVANCED)執(zhí)行計劃:
explain plan for SQL語句;
select * from table(dbms_xplan.display(NULL, NULL,'advanced -projection'));

三.查看帶有A-TIME的執(zhí)行計劃

alter session set statistics_level = all;
select count(*) from test;
select * from table(dbms_xplan.display_cursor(NULL, NULL,'allstats last'));

或者在SQL語句中添加hint:/*+ gather_plan_statistics */
select /*+ gather_plan_statistics */ count(*) from test where owner='SYS';
select * from table(dbms_xplan.display_cursor(NULL, NULL,'allstats last'));

Starts			表示這個操作執(zhí)行的次數(shù)。
E-Rows			表示優(yōu)化器估算的行數(shù),就是普通執(zhí)行計劃中的Rows。
A-Rows			表示真實的行數(shù)。
A-Time			表示累加的總時間。與普通執(zhí)行計劃不同的是,普通執(zhí)行計劃中的Time是假的,而A-Time是真實的。
Buffers			表示累加的邏輯讀。
Reads			表示累加的物理讀。

上面介紹了3種方法查看執(zhí)行計劃。
使用AUTOTRACE或者EXPLAIN PLAN FOR獲取的執(zhí)行計劃來自于PLAN_TABLE。
PLAN_TABLE是一個會話級的臨時表,里面的執(zhí)行計劃并不是SQL真實的執(zhí)行計劃,它只是優(yōu)化器估算出來的。
真實的執(zhí)行計劃不應(yīng)該是估算的,應(yīng)該是真正執(zhí)行過的。SQL執(zhí)行過的執(zhí)行計劃存在于共享池中,具體存在于數(shù)據(jù)字典V$SQL_PLAN中。
帶有A-Time的執(zhí)行計劃來自于V$SQL_PLAN,是真實的執(zhí)行計劃,而通過AUTOTRACE、通過EXPLAIN PLAN FOR獲取的執(zhí)行計劃只是優(yōu)化器估算獲得的執(zhí)行計劃。

四.查看正在執(zhí)行的SQL的執(zhí)行計劃

有時需要抓取正在運行的SQL的執(zhí)行計劃,這時我們需要獲取SQL的SQL_ID以及SQ的CHILD_NUMEBR,然后將其代入下面SQL,就能獲取正在運行的SQL的執(zhí)行計劃。

select * from table(dbms_xplan.display_cursor('sql_id',child_number));

-在一個會話中執(zhí)行如下SQL。
select count(*) from a,b where a.owner=b.owner;

-在另外一個會話中執(zhí)行如下SQL  找出sql的sql_id和child_number
select a.sid, a.event, a.sql_id, a.sql_child_number, b.sql_text
  from v$session a, v$sql b
 where a.sql_address = b.address
   and a.sql_hash_value = b.hash_value
   and a.sql_child_number = b.child_number
 order by 1 desc;
 
-接下來我們將 SQL_ID 和 CHILD_NUMBER 代入以下SQL。
select * from table(dbms_xplan.display_cursor('czr9jwxv0xra6',0));

到此這篇關(guān)于Oracle查看SQL執(zhí)行計劃的幾種方法的文章就介紹到這了,更多相關(guān)Oracle查看SQL執(zhí)行計劃內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論