《檢視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(*) from awr_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=)
---------------------
作者:bisal
來源:CSDN
原文:https://blog.csdn.net/bisal/article/details/40503031
版權聲明:本文為部落客原創文章,轉載請附上博文連結!