天天看點

再談SQL profile : 到底能不能固定執行計劃?

在我釋出了使用coe_load_sql_profile.sql腳本可以解決生産系統執行計劃突然變差的文章後,第二天剛好又看到一篇文章:《執行計劃:Oracle的Profile特性與SQL執行計劃的穩定性》,文章專門對sql profile做了深入的介紹,對了解SQL profile的原理很有幫助。因為撰寫人和轉發者都是業内大拿,粉絲衆多,看了那篇文章的人應該非常多,是以有必要對那篇文章的一個小瑕疵加以糾正,即“SQL profile不能固定執行計劃”這個結論是不準确的,隻是在某種測試條件下的一種結果。

下圖是截取文章的結論部分:

再談SQL profile : 到底能不能固定執行計劃?

在文章作者使用的Test case中,應該确實能得到這樣的結果,但是結論卻不夠完整,會給讀者一個誤導:SQL prfofile不能固定執行計劃。

上述結論是使用oracle的sql tuning advisor工具生成的sql profile(隻寫入一個opt_estimate的有一個hint),作為一個優化工具,對這樣一個SQL不做完全固定也是可以了解的。這個也提醒了我們的DBA,用sql tuning advisor做的sql profile不一定能固定執行計劃。

我想補充說明的是:如果在sql profile寫入了完整的outline data,是可以固定執行計劃的,比如将下面一個SQL完整的Hint的内容寫入profile:

/*+

BEGIN_OUTLINE_DATA

IGNORE_OPTIM_EMBEDDED_HINTS

OPTIMIZER_FEATURES_ENABLE('11.2.0.3')

DB_VERSION('11.2.0.3')

ALL_ROWS

OUTLINE_LEAF(@"SEL$1")

FULL(@"SEL

INDEX(@"SEL

LEADING(@"SEL

USE_NL(@"SEL

NLJ_BATCHING(@"SEL

END_OUTLINE_DATA

*/

這個profile是可以指定SQL使用哪個索引,表的關聯方式和順序。

結論:

sql profile到底能不能固定sql的執行計劃?

答案是取決于你在profile中使用的hint組合是什麼。使用完整的outline data内容就可以固定;使用不完整的,帶有啟發性的hint,就不會固定。

使用coe_sql_load_profile.sql腳本會固定你的SQL的執行計劃(因為它寫入profile中的内容的一個sql完整的outline data執行計劃執行路徑),除非遇到一些特殊情況,如索引不可用、并行資源不夠、資料庫相關參數變更等。