dbms_xplan.display_awr方式擷取執行計畫的實驗和之前的誤導,dbmsxplan.display
《查看Oracle執行計畫的幾種常用方法-系列1》(http://blog.csdn.net/bisal/article/details/38919181)這篇博文中曾提到一個隱藏問題:
“隱藏問題2:
實驗這部分內容發現使用select * from table(dbms_xplan.display_awr('sql_id'));並沒有結果,@黃瑋老師說有可能是AWR收集的是top的SQL,有可能測試用的SQL不是most intensive SQL,但我是用alter system flush shared_pool後執行的手工採集快照,還是未被AWR抓到,比較奇怪的問題,這個也會在另一篇博文中仔細說明。”
背景是:
“select * from table(dbms_xplan.display_awr('sql_id'));
(1)是使用explain plan for +SQL作為前提,(2)和(3)的前提則是SQL的執行計畫還在共用池中,具體講是在庫緩衝中。如果已經被age out交換出共用池,則不能用這兩種方法了。若該SQL的執行計畫被採集到AWR庫中,則可以用(4)上述SQL來查詢曆史執行計畫。”
即使用這條SQL可以查看AWR庫中儲存的執行計畫。但我嘗試用dual表做實驗,發現並沒有被AWR庫儲存他的執行計畫(http://www.itpub.net/forum.php?mod=viewthread&tid=1886046&extra=)。
實驗:
1. 建立測試表:
2. 查詢Shared Pool中是否已經緩衝了select count(*) fromawr_tbl的執行計畫:
3.手工收集AWR報告,清空Shared Pool緩衝池:
看到緩衝區被清空了,剛才可以從v$sqlarea中查詢的SQL資訊已經刪除了。
4. 使用上面提到的“select * from table(dbms_xplan.display_awr('sql_id'));”看看AWR中儲存的SQL資訊:
對於@dbsnake說的dbms_xplan.display_awr('sql_id')和dbms_xplan.display_cursor的區別是不能顯示謂詞資訊,是因為從V$SQL_PLAN匯入AWR基表WRH$_SQL_PLAN時未將謂詞欄位access_predicates和filter_predicates匯入,也做了一個實驗:
select count(*) from sys_awr where object_name='SYS_AWR';語句,在V$SQL_PLAN中存在謂詞資訊:“OBJECT_NAME=”='SYS_AWR',但從WRH$_SQL_PLAN中看這兩個欄位是空的:
總結:
(1) select * from table(dbms_xplan.display);
(2) select * from table(dbms_xplan.display_cursor(null, null, 'advanced'));
(3) select * from table(dbms_xplan.display_cursor('sql_id/hash_value', child_cursor_number, 'advanced'));
(4) select * from table(dbms_xplan.display_awr('sql_id'));
以上是使用dbms包查看執行計畫的四種方法,其中:
(1)需要配合explain plan使用。
(2)、(3)需要SQL仍在Shared Pool中。
(4)需要AWR庫儲存該SQL資訊。另外,不會顯示謂詞資訊。
針對不同的情境選擇不同的讀取執行計畫的方法即可。
實驗過程中我曾用select * from dual作為測試SQL,但未得到如上結果,經@黃瑋大師點播,認為可能是對於DUAL表的操作Oracle內部不是像正常表檢索的方式來執行的,有機會可以探究。(http://www.itpub.net/forum.php?mod=viewthread&tid=1886046&extra=)