天天看點

微服務架構 | 如何優化日志鍊路追蹤輸出 SQL 的執行效率?

導讀:檢視 SQL 的執行效率,不難想到使用 explain 分析慢查詢,但是前提是你需要非常了解業務背景。否則很難精準定位到。

系統都是逐漸演進的,一個系統在運作中必須是根據場景逐漸地提高優化性能。高并發就是對資源的節約的考驗,這種考驗除了更換優秀和先進的技術,優化架構,還在于從小處出發,對盡可能節約的資源進行節約。

而在一個系統的資料通路中,系統的瓶頸往往是來自于資料庫,是以我們要盡可能減少對資料庫的通路!

有沒有遇到這種情況,上司突然安排一件事情:這幾個接口壓測名額太低需要針對性優化一下。

當然理想的情況下你對業務場景非常熟悉,可以大概定位問題來分析業務精準評估哪些 SQL 會有性能瓶頸。

然後開始百度:如何提高 SQL 執行效率?

通過 explain、show profile 和 trace 等診斷工具來分析慢查詢。

但是大多數情況下業務線過長,不可能一個人完成。涉及到各種政策模式、監聽動作。想直接定位到點還是需要輸出請求發起後所觸發的執行的 SQL 以及執行效率。這裡效率單單指代 SQL 執行的時間。

目标明确後開始整活吧。

繼續前一篇文章的話題:如何利用好日志鍊路追蹤做性能分析?

微服務架構 | 如何優化日志鍊路追蹤輸出 SQL 的執行效率?

要想處理此類問題首先的分析,SQL 執行時間計算如何來劃分?SQL 的語句執行過程大緻如下圖所示。

微服務架構 | 如何優化日志鍊路追蹤輸出 SQL 的執行效率?

如果想統計 SQL 執行時間。是以對于程式而言可以得到粗略公式 

閱讀過 Hibernate 或者 MyBatis 等持久化架構的應該比較了解 Statement 位于 java.sql 基礎包下 

微服務架構 | 如何優化日志鍊路追蹤輸出 SQL 的執行效率?

Statement 提供了用于執行靜态 SQL 語句并傳回它産生的結果的對象。預設情況下,每個 Statement 對象隻能同時打開一個 ResultSet 對象。

是以,如果一個 ResultSet 對象的讀取與另一個的讀取交錯,則每個對象都必須由不同的 Statement 對象生成。如果存在打開的對象,則 Statement 接口中的所有執行方法都會隐式關閉該 Statement 的目前 ResultSet 對象。

繼續檢視源碼可以發現在 Statement 提供了用于執行方法後,PreparedStatement 預編譯 SQL 語句的對象。SQL 語句被預編譯并存儲在 PreparedStatement 對象中。然後可以使用此對象多次有效地執行此語句。

微服務架構 | 如何優化日志鍊路追蹤輸出 SQL 的執行效率?

為了驗證這個思路,可以借鑒其他定制化資料庫驅動。

微服務架構 | 如何優化日志鍊路追蹤輸出 SQL 的執行效率?

定義 StatementWraper 實作 Statement 提供了用于執行靜态 SQL 語句并傳回它産生的結果的對象。

微服務架構 | 如何優化日志鍊路追蹤輸出 SQL 的執行效率?
微服務架構 | 如何優化日志鍊路追蹤輸出 SQL 的執行效率?

記錄日志詳情

微服務架構 | 如何優化日志鍊路追蹤輸出 SQL 的執行效率?

這樣就有了文章開頭的程式執行過程中鎖觸發的 SQL 執行耗時情況。

微服務架構 | 如何優化日志鍊路追蹤輸出 SQL 的執行效率?

同理定義 PreparedStatementWraper 實作 PreparedStatement

微服務架構 | 如何優化日志鍊路追蹤輸出 SQL 的執行效率?

最後日志輸出使用 logback 元件進行日志采集

對這類問題先前有做介紹

微服務分布式架構中,如何實作日志鍊路跟蹤?

如何利用好日志鍊路追蹤做性能分析?