只需三步!慢日誌去無蹤

| 做者 王文安,騰訊CSIG數據庫專項的數據庫工程師,主要負責騰訊雲數據庫 MySQL 的相關的工做,熱愛技術,歡迎留言進行交流。數據庫


做爲一個 DBA,想必都有過被慢查詢折騰的經歷,一個慢查詢有時候真的很讓人抓狂,本文對常規和很是規手段進行了整理,由淺及深,簡單介紹幾個慢查詢的分析手段。服務器

須要說明的是,下面全部的手段都是原生支持的功能(≥MySQL 5.6),所以在各種 RDS 和原生數據庫中都不會有什麼使用上的差別,這裏圖方便就用騰訊雲數據庫 MySQL 來做爲測試環境了,版本爲 5.7。session

第一步:EXPLAIN工具

最早登場的毫無疑問就是 EXPLAIN 語句了,用過 MySQL 的人應該都知道這個查看 SQL 語句執行計劃的命令,詳細的資料在網上有不少,這裏就略過了。通常來講,95% 的慢查詢問題只須要 EXPLAIN 就能夠解決了。手工執行的時候,在 Extra 列裏面,避免出現Use Temporary Table和Using file sort這類關鍵字,TYPE 列中也儘可能避免 ALL 類型(全表掃描)出現。測試

其實目前這個最經常使用的功能在騰訊雲上能夠直接用 DBbrain 來進行操做了。DBbrain 會分析 SQL 語句並給出加索引的建議。在DBbrain中選擇對應的實例,進入 SQL 診斷的 tab 下,點擊具體的慢查詢就能夠看到加索引的建議了:優化

image.png

第二步:PROFILEorm

既然 EXPLAIN 能看到 SQL 的執行計劃,能判斷出來有沒有好好利用索引,DBbrain 也能給出索引的優化建議,那麼慢查詢的分析爲何還會有三步曲?blog

緣由很簡單,MySQL 慢查詢,並不必定慢在有沒有索引;SQL 的執行環節中任意一環出了問題都會表現爲查詢變慢,因此用了索引,EXPLAIN 的結果也很完美,可是仍是慢,怎麼辦?索引

這時候,就須要 PROFILE 來幫忙了,這個命令能夠詳細的列出 SQL 語句在每個步驟消耗的時間,前提(缺點)是先執行一遍語句。隊列

PROFILE 默認是關閉的,因此須要在 client 端先打開,操做以下:

set session profiling = 1;

在實際的生產環境中,可能會須要加大profile的隊列,保證想要查看的 PROFILE 結果還保存着,所以能夠用以下操做來增長 PROFILE 的隊列大小

set session profiling_history_size = 50;

到這一步,PROFILE 的功能就開啓了,這裏先刪除索引,簡單試一下 SQL 語句,EXPLAIN 一下看看輸出

image.png

TYPE 列是 ALL,顯然這種語句是不合格的,「假設」索引「以爲」沒問題,可是這個語句仍是比預想的要慢,那麼能夠看看這條語句各個階段的耗時,先執行一次 select,而後再查看 PROFILE 的結果:

image.png

能夠看到 id 爲 11 的那一行就是執行過的語句,這時候使用show profile block io,cpu,memory,source for query 11;來查看統計信息:

image.png

Sending data 並不僅是在服務器端和客戶端之間 Sending data,還包括了從磁盤讀取數據的時間,由於這個查詢執行了全表掃描,因此這個時間會比較高,固然索引的效率不高也會致使這部分時間比較久。

若是還有 order by 的話,這裏面也會出現 Sort 相關的信息。

通過了這兩部曲以後,基本上一個 SQL 爲何慢,慢在哪裏基本上能夠定位出來了,那麼最後的手段主要是解決什麼問題呢?

第三步:OPTIMIZER_TRACE

OPTIMIZER_TRACE 是 MySQL 5.6 添加的新功能,顧名思義,這個功能能夠看到內部查詢計劃的 TRACE 信息,從而能夠知道 MySQL 是如何在衆多索引中選中最「棒」的那個。通常來講,這個最「棒」的索引選錯了,就須要根據 OPTIMIZER_TRACE 的信息來判斷爲何會選錯,是 MySQL 的配置緣由,仍是 SQL 某些地方寫的很差致使 MySQL 誤判了。

開啓這個功能的方式以下:

set session optimizer_trace='enabled=on';

隨便執行一個 EXPLAIN 語句,生成一個執行計劃,而後在information_chema.optimizer_trace的表裏面查找這一條語句對應的信息:

image.png

內容是很是長的 JSON 格式,因此推薦把結果轉存到其餘地方,而後用 JSON 的轉換工具來輔助查看,若是要看索引的選擇狀況,就重點關注這個 JSON 的ref_optimizer_key_uses,rows_estimation 及以後的部分,這裏會展現索引選擇相關的信息,截取一部分結果做爲示例:

image.png

在這裏面能看到詳細的統計信息,包括 cost,預計的 rows,在以後的內容中也會顯示最終選擇的索引:

image.png

一般來講,cost 數值越低,表明這個執行計劃的執行速度越快。

總結

其實在絕大多數的狀況下,EXPLAIN 徹底能夠勝任,在騰訊雲平臺上的話,用 DBbrain 便可,PROFILE 通常是用來決定分析和判斷的方向,看看是哪一個階段比較慢。OPTIMIZER_TRACE 主要用來分析各類疑難雜症,好比說優化器爲何沒有選擇索引而是全表掃描?爲何優化器沒有選擇效率較好的索引,而是選擇了一個效率較差的索引(order by,limit)等等。

總而言之,經過這三步曲的排查,基本上 SQL 的問題就都能找出來了,好好掌握這些基本技能對於 DBA 來講仍是頗有用的。

本文由博客一文多發平臺 OpenWrite 發佈!

相關文章
相關標籤/搜索