MySQL效能優化之簡單sql改寫

DBA_每日記發表於2019-11-12

1> 

問題描述

某客戶集團反饋某模組崩潰,導致系統異常,系統無法登陸;

關閉該模組瀏覽模組後,系統才恢復正常問題重複出現多次。


處理過程

協助排查問題優化過程中發現查詢該模組的一個長SQL導致效能問題,其中引發問題的主要原因在下圖中的部分SQL片段:

 

以上SQL中workflowtye在流程表中存放的為int型別,而子句中的content確為char型別,兩個型別不同的欄位進行關聯比較時,導致索引失效。

修改conten的欄位型別為int之後SQL效能恢復正常。

在表設計初期,應將需要進行關聯的欄位型別設定為同一型別。否則會帶來嚴重的效能問題,後期修改的難度將更大。


2> 

問題描述

配合客戶上線壓測期間,發現某介面查詢SQL在資料量比較大時效能無法滿足客戶要求,需進行改造優化


處理過程

該SQL的查詢邏輯耗時主要在排序分頁上,SQL精簡之後的邏輯如下:

 

 

優化的思路如下:

類似這種分頁+排序的SQL,第一種書寫的邏輯,在使用createdate和createtime進行排序時,需要通過主鍵回表查詢帶出其他附帶的欄位資訊,

雖然可以利用到索引,但是這種邏輯並非最高效的,尤其再分頁越靠後的時候,隨著偏移量加大,需要拿到記憶體中的資料就更多,查詢耗時就更久。

而第二種SQL的書寫方法,requestid和createdate,createtime欄位上均有索引,在進行排序和分頁時,只需要檢索索引即可完成(MySQL的覆蓋索引概念),

只獲取到分頁之後的requestid值再與外部表進行inner join,查詢速度會極大的提升,並且查詢效率不會因為分頁靠後而明顯下降。


3> 

問題描述

客戶環境資料庫CPU出現告警資訊,協助進行排查資料庫相關問題。


處理過程

通過慢日誌分析對資料庫的整體效能分析並進行了優化。

此處列舉我們程式中常用的一個問題邏輯:

部分SQL片段如下

 

 

程式碼中較多的SQL發現開發人員習慣使用exists邏輯來過濾資料,但是在MySQL中,exists的效能並不是最高的,即使在欄位存在索引的情況下,在結結果集比較大情況下,

exists的檢索速度遠不如inner join的hash連線,而且過多的使用exists容易導致SQL的執行計劃異常,而inner join邏輯相對更加直接,簡化。

我們推薦的優先邏輯:join  >  exists  >  in


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69950231/viewspace-2663624/,如需轉載,請註明出處,否則將追究法律責任。

相關文章