系統都是逐漸演進的,一個系統在運行中必須是根據場景逐漸地提高優化性能。高并發就是對資源的節約的考驗,這種考驗除了更換優秀和先進的技術,優化架構,還在于從小處出發,對盡可能節約的資源進行節約。
而在一個系統的數據訪問中,系統的瓶頸往往是來自于數據庫,因此我們要盡可能減少對數據庫的訪問!
一、背景
有沒有遇到這種情況,領導突然安排一件事情:這幾個接口壓測指標太低需要針對性優化一下。
當然理想的情況下你對業務場景非常熟悉,可以大概定位問題來分析業務精準評估哪些 SQL 會有性能瓶頸。
然后開始百度:如何提高 SQL 執行效率?
通過 explain、show profile 和 trace 等診斷工具來分析慢查詢。
但是大多數情況下業務線過長,不可能一個人完成。涉及到各種策略模式、監聽動作。想直接定位到點還是需要輸出請求發起后所觸發的執行的 SQL 以及執行效率。這里效率單單指代 SQL 執行的時間。
目標明確后開始整活吧。
二、添加 JDBC 追蹤
繼續前一篇文章的話題:如何利用好日志鏈路追蹤做性能分析?
? SQL 執行時間公式
要想處理此類問題首先的分析,SQL 執行時間計算如何來劃分?SQL 的語句執行過程大致如下圖所示。
如果想統計 SQL 執行時間。所以對于程序而言可以得到粗略公式
SQL執行時間=提取數據之后時間-語法解析開始時間
? 添加增加 JDBC 追蹤
閱讀過 Hibernate 或者 MyBatis 等持久化框架的應該比較了解 Statement 位于 java.sql 基礎包下
Statement 提供了用于執行靜態 SQL 語句并返回它產生的結果的對象。默認情況下,每個 Statement 對象只能同時打開一個 ResultSet 對象。
因此,如果一個 ResultSet 對象的讀取與另一個的讀取交錯,則每個對象都必須由不同的 Statement 對象生成。如果存在打開的對象,則 Statement 接口中的所有執行方法都會隱式關閉該 Statement 的當前 ResultSet 對象。
繼續查看源碼可以發現在 Statement 提供了用于執行方法后,PreparedStatement 預編譯 SQL 語句的對象。SQL 語句被預編譯并存儲在 PreparedStatement 對象中。然后可以使用此對象多次有效地執行此語句。
為了驗證這個思路,可以借鑒其他定制化數據庫驅動。
定義 StatementWraper 實現 Statement 提供了用于執行靜態 SQL 語句并返回它產生的結果的對象。
記錄日志詳情