Oracle執行計劃之SQL優化

前段時間一個項目頻繁報weblogic相關的錯誤,具體錯誤如下爲:

 <[ACTIVE] ExecuteThread: '15' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <> <1464601972012> <BEA-000337> <[STUCK] ExecuteThread: '5' for queue: 'weblogic.kernel.Default (self-tuning)' has been busy for "608" seconds working on the request "Workmanager: default, Version: 0, Scheduled=true, Started=true, Started time: 608295 ms

", which is more than the configured time (StuckThreadMaxTime) of "600" seconds. Stack trace:
java.net.SocketInputStream.socketRead0(Native Method)
java.net.SocketInputStream.read(SocketInputStream.java:129)
oracle.net.ns.Packet.receive(Packet.java:300)
oracle.net.ns.DataPacket.receive(DataPacket.java:106)
oracle.net.ns.NetInputStream.getNextPacket(NetInputStream.java:315)
oracle.net.ns.NetInputStream.read(NetInputStream.java:260)
oracle.net.ns.NetInputStream.read(NetInputStream.java:185)
oracle.net.ns.NetInputStream.read(NetInputStream.java:102)
oracle.jdbc.driver.T4CSocketInputStreamWrapper.readNextPacket(T4CSocketInputStreamWrapper.java:124)
oracle.jdbc.driver.T4CSocketInputStreamWrapper.read(T4CSocketInputStreamWrapper.java:80)
這個問題最終結果導致weblogic server線程阻塞,server最初報出警告、最後宕機,因爲weblogic server是一個集羣環境,每個server最大線程數也很少,最大線程數大致在25,雖然執行時間超過600s後,weblogic本身會回收線程,但在某一段時間訪問用戶比較多時,server還是經常宕機,這樣問題就比較嚴重,所以得儘快排查並解決該問題。

後續安排人員進行排查,首先將該業務報錯的sql在sql plus中進行執行,執行時間雖然有些慢,大致在5~6秒,重複執行幾次也差不多是這個時間,這時判斷該錯誤應該和sql執行效率沒有關係,sql如下:

SELECT
*
FROM
(
SELECT
o.*, Rownum rowno
FROM
(
SELECT
con1.res_id,
conrel.title,
conrel.class_id,
con1.res_abstract,
con1.title_img,
con1.res_author,
con1.res_wordcount,
con1.res_content,
con1.res_type,
con1.res_keywords,
con1.editor,
con1.person,
con1.job,
conrel.pub_date,
(
CASE
WHEN con1.RES_TYPE = 0 THEN
1
ELSE
0
END
) AS con_type,
con1.enter_type,
con1.url,
con1.res_id AS source_id,
con1.thumb_img,
con1.medium_img,
con1.media_url,
con1.PRODUCT_COLUMN_ID AS master_id,
con1.RES_SUBTOPIC,
con1.product_id,
con1.pre_type,
con1.tpl_id,
con1.res_catid,
con1.res_catname,
con1.CAT_REGION,
con1.RES_SOURCE,
con1.small_img,
con1.large_img,
con1.html_url,
con1.tag_id,
con1.tag_name,
con1.cat_regionid,
con1.video_flv_300,
con1.video_flv_500,
con1.video_flv_1024,
con1.video_mp4_300,
con1.video_mp4_500,
con1.video_mp4_1024,
con1.GOODS_ID,
con1.GOODS_TYPE
FROM
eps_product_res con1,
tp_con_class_rel conrel
WHERE
con1.res_id = conrel.con_id
AND conrel. STATUS = 2
AND conrel.class_id = 51
AND con1.enter_type = 0
AND conrel.pub_date >= to_date (
'2016-06-01 00:00:00',
'yyyy-MM-dd HH24:mi:ss'
)
AND conrel.pub_date <= to_date (
'2016-06-28 00:00:00',
'yyyy-MM-dd HH24:mi:ss'
)
ORDER BY
conrel.display_order ASC,
pub_date DESC
) o
)
WHERE
1 = 1
AND rowno >= 0
AND rowno <= 30


判斷可能問題是在用戶單位網絡延遲或者weblogic 本身的虛擬機器(這裏說一下用戶weblogic部署的服務器爲虛擬機),這種問題不就不太好判斷了,因爲用戶單位網絡複雜、各部門關係也複雜,協調起來遲緩、麻煩,剛好在中間一段時間內有國家領導出訪,用戶訪問量在這段時間比較平常多,導致weblogic server頻繁出現警告及宕機,沒轍,只能人爲重啓,還好是集羣環境,重啓其中部分server用戶感覺不到。就這麼噁心的臨時重啓來解決問題,連週末都沒過好,得有人盯着server的運行情況。

問題沒解決還得繼續想辦法解決,於是繼續找用戶協調數據庫相關部門配合排查,同時程序也加調試日誌,輸出執行時長,通過調試日誌執行時長來看,確實頻繁出現業務sql執行大於600s情況,但就是無法判斷是在數據庫本身還是在網絡上,因爲之前手動執行sql沒出現過這麼慢的情況,後續和合作廠商進行交流,說他們也出現了這種情況,正常sql執行挺快,但是也會出現比較慢,出現執行比較慢的原因是沒有走oracle的執行計劃,執行計劃具體機制也不清楚,可能需要優化sql,但這sql相對也不復雜,重寫影響會比較大,因爲整個系統用此類sql的地方較多,所以一時也沒想好怎麼來解決,後來用戶協調到了oracle工程師過來進行交流,還是oracle工程師給力,給出sql會出現不走執行計劃的情況,但具體原因不明(我沒參加這次交流),最後oracle工程師給了一些解決建議:
1、在這條sql中加一個時間限制範圍條件,加了就讓oracle每次都走執行計劃,我猜的。
2、針對where後面有限制條件的屬性加上索引,應該是提高執行時間。
3、分頁條數限制rowno放到內層語句中,難道也是爲了sql執行都走執行計劃,沒弄明白。
後面按這些建議對sql做了優化,果然最近兩三週沒有再出現類似的問題,問題應該是解決了,但sql執行計劃機制沒有弄明白,後面得花些時間研究。


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