應用程序執行週期性時快時慢問題解決一例

       作Oracle DBA,常常會遇到一些性能問題,有些性能問題是一開始就很慢的,有些性能問題是逐漸變慢的,有些性能問題是忽然變慢的,而有性能問題時快時慢的,不知道其餘同行以爲哪一種性能問題比較好處理,今天我在這裏分享一個性能問題週期性問題時快時慢的案例,用於總結反思,若有錯誤請不吝指正。sql

       最近一位應用運維同事發郵件請求協助,反映有一套應用系統跑批期間週期性時快時慢,並且很規律。週一到週五晚上批量的計算耗時很長,要6-8小時;而週六和週日晚上批量計算耗時很快,只須要15分鐘左右。看到郵件中描述的這一現象,有經驗的老司機可能一會兒就想到了問題可能出如今哪裏。但對於經驗不足我來講,解決這種問題仍是比較吃力的。
數據庫

        因而拉了一個微信羣,在羣裏詳細詢問了,跑批快和慢的具體時間。這裏多提一句,在我接手這個case以前有一個同事也查了這個問題,他根據awr從dbtime到redo log生成量再到事務都作了一些分析,還作成了折線圖,在羣裏發了一堆,但就是沒有作一些詳細的詢問和分析。最終也沒有一個結論。
微信

        言規正傳,從開發和應用運維那裏獲得一些詳細信息以後,首先從awr下手。分別取到快的時間和慢的時間區間的awr報告。以個人能力,從各項指標沒有看出數據庫總體負載有什麼問題。但在top SQL那部分發現了兩個時間段的TOP SQL確實是不一樣的。在慢的時間段有一條update語句73320次,耗時9869.7s,而在快的時間段的TOP SQL中卻沒有顯示這條update語句。難道這就是問題所在嗎?運維

        因而詢問開發同事,update語句是否爲批量期間執行的語句。獲得確定的答覆後,開始懷疑是否是工做日和週末跑批的邏輯不一樣的,但awr中信息否認了個人猜想,原來這條update語句也在週末也跑了,只不是跑的很快,跑了75331次,耗時24.07s。從目前 的線索來看,之條update語句執行效率無疑是致使程序批量時快時慢的緣由。可是爲何會出現這種現象如今還不得而知。ide

        問題sql定位了,剩下的問題就簡單了,把sql優化掉,每次批量都在24s完成,那問題天然就解決了。如今開始尋找sql執行時快時慢的緣由。這裏介紹一個很強大的工具awrsqrpt,這個工具能夠獲取awr中記錄的sql語句的歷史執行計劃。使用awrsqrpt取到兩個時間段sql的執行計劃,分別以下兩個圖所示:
工具

1.png2.png

        從執行計劃中能夠看出,都走了表的主鍵,選擇了不一樣的方式,其中INDEX RANGE SCAN平均單次執行時間爲384.3ms,而INDEX SKIP SCAN的平均單次時間是0.3ms,差了3000多倍,難怪批量執行時間差別如此之大。看到這個,腦子中反映出來的第一個解決方法是固定執行計劃,強制走INDEX SKIP SCAN。但這種方法治標不治本。只能用在實在找不到問題緣由的狀況下,或緊急的狀況下。性能

        繼續與開發溝通,得知,update語句中的表,天天批量後都會被truncate掉,這是一個很重要的信息。難道就是因爲這一個truncate操做致使sql語句執行效率差別如此之大嗎?咱們繼續往下分析。
優化

        咱們都知道,Oracle的執行計劃都是經過CBO,根據表上的統計信息,而估算出來Oracle認爲最作優的執行計劃。也就是不論INDEX RANGE SCAN 仍是SKIP SCAN,Oracle都認爲是最優的,難道是Oracle優化器出現了問題了嗎?應該不是的,若是優化器這麼容易出問題,那Oracle在商用數據庫也不會稱霸這麼久了。因而想到了表上的統計信息,經過查詢視圖sys.wri$_optstat_tab_history獲得表上的歷史統計信息以下圖:
blog

3.png

        從上面的圖上能夠看到,表上的統計信息時而爲0,時而爲很大,看來就是統計信息致使CBO在選擇執行計劃時,沒有選擇它應該選的最優執行計劃。事務

        從上面的分析來看,應該是找到了問題的根本緣由,批量表每次批量完成後都會作truncate操做,數據庫默認天天都會自動收集表的統計信息,週一到週五22:00開始收集,週末6:00開始收集。從而致使數據庫在不一樣時間點收集到表的統計信息是不一樣的,進而致使了優化器基於統計信息來選擇了慢的執行計劃。

        緣由找到了,就開始討論解決方法,這裏列出來幾種方法應該均可以解決這個問題:

        一、在批量導入數據後,對批量表作一次統計信息收集

        二、鎖定批量表在有數據時的統計信息

        三、truncate操做改成批前執行(開發提出)

        四、固定問題sql的執行計劃(可能解決不了問題)

        反思:

        一、咱們在解決問題時,不能只從數據庫總體層面來分析,有時多是一條自己性能不是不好的sql致使出的性能問題

        二、多溝通、細溝通,把儘量掌握多的信息點,有助於問題的解決

        三、從性能慢的sql中應該也能夠猜測到問題緣由,Oracle評估的cost 爲0

        以上爲整個case的一個解決過程,歡迎指正。

相關文章
相關標籤/搜索