merge語句導致的效能問題緊急優化

2021-09-22 18:59:39 字數 2152 閱讀 7025

晚上正在休息的時候,突然收到一封報警郵件。

報警內容: cpu utilization is too high

------------------------------------

報警級別: problem

------------------------------------

監控專案: cpu idle time:59.11 %

------------------------------------

這個報警資訊已經非常明確,cpu使用率很緊張了。這台伺服器上執行著oracle和mysql例項,所以第一感覺是不是mysql的慢查詢導致的,結果登入到伺服器端,發現mysql的連線數很少,沒有發現慢查詢,那麼問題很可能就和oracle有關係了,使用top檢視,果然幾個top的程序都是帶有local=no的字樣,很可能是應用端觸發的sql導致。

檢視v$session的資訊,發現其中乙個會話已經執行一條sql超過了40分鐘。這個sql是merge語句,看來merge又攤上事了。

語句的內容如下:

我們來看看語句的執行計畫情況,如下:

可以明顯看到乙個全表掃瞄,這個表中的資料大概是700多萬,就算全表掃瞄也應該幾分鐘就出結果了。怎麼執行了40分鐘了還沒有任何反應。

我們來看看執行的瓶頸在**。還是使用sql monitor來定位,一目了然。

可以明顯看出瓶頸在全表掃瞄的部分。

表中的資料有700多萬,而經過排查發現竟然沒有任何索引。所以問題的原因就更加明顯了。

我們需要再總結一下,問題的原因定位到了,執行計畫的效率極低。怎麼改進。

1.建立索引,這就無形帶來幾個問題,基於哪些列來建立索引

2.這個表中目前存在頻繁的dml操作,如何建立索引

3.為什麼執行計畫的消耗如此之大

我們來乙個乙個看問題,首先是建立索引,這個看起來目標明確,但是具體來做,就需要一些技巧了, 對於這類的問題,個人比較偏好dbms_sqltune.report_tuning_task,因為呼叫方便,簡單而且能很快出結果。不到1分鐘分析結果就出來了,提出了3點建議,乙個就是收集統計資訊,乙個是修改sql profile,還有乙個就是建立索引,我們的目標明確,就是索引的改進,建議裡面會根據資料的選擇度來進行評估和分析,還是比較全面的。

但是建立索引的過程中,這個ddl肯定會排斥其他的dml,很容易出現這樣的錯誤。

這種情況下,新特性ddl_lock_timeout就值得推薦了,我們可以設定乙個略微長一些的超時時間,讓它在後台自己去試,很快就能得到結果。

回頭一看前兩個問題已經解釋了,那麼第3個問題,為什麼執行計畫的差別如此之大,就算全表也不至於那麼慢啊。

語句的謂詞部分會做出解釋:

可以看到走了filter過濾,using部分和表中的資料對映存在重大的偏差,內部的對映竟然是一大堆的case when的形式。

當然這個語句優化之後,效能提公升也很明顯。精確到分鐘級,效果提公升還是不錯的。

ASP中SQL語句導致的效能問題

今天,修改了一點上次做的辦公管理系統中的檔案上傳的bug,原因是asp中sql語句效能問題導致了recordset物件關閉,結果使資料入庫失敗。對於這個錯誤,我目前只能這樣理解了 sql語句 select from tab files 開啟表後,然後呼叫addnew方法新增要更新的資料,表面上看沒什...

ASP中SQL語句導致的效能問題

今天,修改了一點上次做的辦公管理系統中的檔案上傳的bug,原因是asp中sql語句效能問題導致了recordset物件關閉,結果使資料入庫失敗。對於這個錯誤,我目前只能這樣理解了 sql語句 select from tab files 開啟表後,然後呼叫addnew方法新增要更新的資料,表面上看沒什...

SWAP導致的效能問題

db維護過程中,我們常說的使用太多swap會導致效能問題,原因是 當應用程式要請求新的記憶體頁的時候,如果已經沒有足夠的物理記憶體,就會把目前物理記憶體中的一部分空間釋放出來,以供當前執行的程式使用。這部分被釋放的空間可能屬於某乙個程式,並且所謂的釋放,是把這部分記憶體頁存放到swap空間。如果這個...