碼農(nóng)架構(gòu) | 如何利用日志鏈路追蹤程序執(zhí)行的慢 SQL?

系統(tǒng)都是逐漸演進(jìn)的,一個系統(tǒng)在運(yùn)行中必須是根據(jù)場景逐漸地提高優(yōu)化性能。高并發(fā)就是對資源的節(jié)約的考驗(yàn),這種考驗(yàn)除了更換優(yōu)秀和先進(jìn)的技術(shù),優(yōu)化架構(gòu),還在于從小處出發(fā),對盡可能節(jié)約的資源進(jìn)行節(jié)約。

而在一個系統(tǒng)的數(shù)據(jù)訪問中,系統(tǒng)的瓶頸往往是來自于數(shù)據(jù)庫,因此我們要盡可能減少對數(shù)據(jù)庫的訪問!

一、背景


有沒有遇到這種情況,領(lǐng)導(dǎo)突然安排一件事情:這幾個接口壓測指標(biāo)太低需要針對性優(yōu)化一下。

當(dāng)然理想的情況下你對業(yè)務(wù)場景非常熟悉,可以大概定位問題來分析業(yè)務(wù)精準(zhǔn)評估哪些 SQL 會有性能瓶頸。

然后開始百度:如何提高 SQL 執(zhí)行效率?

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

但是大多數(shù)情況下業(yè)務(wù)線過長,不可能一個人完成。涉及到各種策略模式、監(jiān)聽動作。想直接定位到點(diǎn)還是需要輸出請求發(fā)起后所觸發(fā)的執(zhí)行的 SQL 以及執(zhí)行效率。這里效率單單指代 SQL 執(zhí)行的時間。

目標(biāo)明確后開始整活吧。

二、添加 JDBC 追蹤


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

image

? SQL 執(zhí)行時間公式

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

image

如果想統(tǒng)計(jì) SQL 執(zhí)行時間。所以對于程序而言可以得到粗略公式

SQL執(zhí)行時間=提取數(shù)據(jù)之后時間-語法解析開始時間

? 添加增加 JDBC 追蹤

閱讀過 Hibernate 或者 MyBatis 等持久化框架的應(yīng)該比較了解 Statement 位于 java.sql 基礎(chǔ)包下

image

Statement 提供了用于執(zhí)行靜態(tài) SQL 語句并返回它產(chǎn)生的結(jié)果的對象。默認(rèn)情況下,每個 Statement 對象只能同時打開一個 ResultSet 對象。

因此,如果一個 ResultSet 對象的讀取與另一個的讀取交錯,則每個對象都必須由不同的 Statement 對象生成。如果存在打開的對象,則 Statement 接口中的所有執(zhí)行方法都會隱式關(guān)閉該 Statement 的當(dāng)前 ResultSet 對象。

繼續(xù)查看源碼可以發(fā)現(xiàn)在 Statement 提供了用于執(zhí)行方法后,PreparedStatement 預(yù)編譯 SQL 語句的對象。SQL 語句被預(yù)編譯并存儲在 PreparedStatement 對象中。然后可以使用此對象多次有效地執(zhí)行此語句。

image

為了驗(yàn)證這個思路,可以借鑒其他定制化數(shù)據(jù)庫驅(qū)動。

image

定義 StatementWraper 實(shí)現(xiàn) Statement 提供了用于執(zhí)行靜態(tài) SQL 語句并返回它產(chǎn)生的結(jié)果的對象。

image
image

記錄日志詳情

image
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容