Oracle相同的一個SQL執行計劃截然不同的解決方法

最近在項目中遇到了一個很奇怪的問題,有個結構稍微複雜點的SQL(left join了十幾張表)在一個項目地A查詢時兩秒返回數據,但是相同的SQL部署在另外一個項目地B卻花費90多秒,更奇怪的是項目地B的數據庫服務器比A好很多,還有數據總行數也比項目地A的少一些,然而花費的時間卻多了幾十倍。這個時候我比較了一下兩個項目地該條sql的執行計劃,發現執行計劃是截然不同的。

剛開始一直以爲是SQL層面的問題,不斷嘗試優化對應的索引,經過優化後,項目地B還是需要花費40多秒,感覺SQL層面很難進行優化了,我已經盡力了,這時候就開始懷疑會不會是其他原因,如數據庫安裝問題,數據庫配置信息pga、sga參數等。

最後,只能選擇求助公司的DBA同事,經過DBA三個多小時的努力,終於找出問題所在:

對於執行計劃中,在note部分如果有“cardinality feedback used for this statement”,表示使用了基數反饋(Cardinality Feedback)。基數反饋(Cardinality Feedback)是Oracle 11.2開始Oracle有了一種新的特性,Cardinality Feedback是一個優化器自動優化的過程,優化器會自動修正重複執行的查詢的執行計劃。對於一些複雜的查詢,比如多字段條件,字符串範圍比較,數據SKEW等等,以及缺乏統計信息,優化器可能不能夠產生一個完全準確的基數估計, 如丟失或統計數據不準確,或複雜的謂詞的基數估計。cardinality feedback 就是基於這一原因而產生的。_optimizer_use_feedback參數默認是TRUE,即開啓Cardinality Feedback,FALSE爲關閉Cardinality feedback。

解決方法:關閉oracle的一個參數,對於結構上不復雜的語句

alter system set "_optimizer_use_feedback"=false;

設置完後,重新執行SQL,一秒就查詢出來了;接下來反覆執行sql,發現執行時間恢復正常。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章