糾正了一直的理解誤區

lsl031發表於2011-08-31

還是接著前天的關於執行計劃觸發bug的研究:
前天說了可以嘗試重新收集統計資訊,重新建立表等方式進行對語句執行計劃的修改。
今天說幹就幹,執行
EXEC DBMS_STATS.gather_table_stats(ownname => 'AUTOCLAIM',tabname => UPPER('lp_flow_state'),estimate_percent => 80,method_opt=> 'for all indexed columns',cascade=>true,degree => 2);
以及其他幾個表的統計資訊一併重新收集了下,但是發現執行計劃仍然沒有變(透過toad檢視執行計劃的方式檢視)
更鬱悶的是,居然在v$sql_plan中無法查詢到對應的語句。
怎麼回事呢?不是說對語句中的物件做個ddl ;重新收集統計資訊就可以重新生成執行計劃嗎?難道是這個執行計劃真是最優的?
但從實際角度看,肯定是不對的。找動態檢視沒有查詢到這個資訊就更怪了。
難道我的理論存在一個很大的錯誤?原來我一直認為檢視執行計劃後,在共享池就存在執行計劃了
如果是非要語句執行後,才會產生執行計劃到共享池,那麼我遇到的問題就不是問題,而且糾正了我一直存在的理解誤差。
那麼來進行一下驗證:
select * from t1;(只檢視執行計劃)
 select * from v$sql where sql_text like 'select * from t1%'
----沒有結果
select * from t1;(實際執行)
 select * from v$sql where sql_text like 'select * from t1%'
----存在結果。
簡單的測試,就糾正了原來存在的誤差。


帶來一個新問題,如果我們現在發現語句執行計劃由於繫結變數最初帶入的變數值存在嚴重的問題,想清除掉這個執行計劃。讓它在帶入合適的繫結變數進行執行計劃的生成?
檢視網路上的資訊,棉花糖的一篇文章給了一些幫助。
 select * from v$sql where sql_text like 'select * from t1%'
----查出sql地址和hash_value
exec sys.dbms_shared_pool.purge('0700000A0D2C7DC8,1468955422','C');   ---前面是地址,後面是hash_value
檢視 select * from v$sql where sql_text like 'select * from t1%'
仍然存在記錄。

原來還要設定一個事件才可以觸發:
alter session set events '5614566 trace name context forever';

再執行exec sys.dbms_shared_pool.purge('0700000A0D2C7DC8,1468955422','C');
select * from v$sql where sql_text like 'select * from t1%'
不存在記錄,操作生效了。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/288166/viewspace-706304/,如需轉載,請註明出處,否則將追究法律責任。

相關文章