當生產數據量急劇增長后,很多SQL語句可能會開始暴露出性能問題。當面對一個有SQL性能問題的數據庫時,應該從何處入手進行系統的分析,使得能夠盡快定位到問題SQL處並盡快解決問題?
第一步:查看SQL執行頻率
MySQL客戶端連接成功后,通過show [session|global] status命令可以提供服務器狀態信息。show [session|global] status可以根據需要加上參數“session”或者“global”來顯示session級(當前連接)的統計結果和global級(自數據庫上次啟動至今)的統計結果。如果不寫,默認使用session。
顯示當前session所有參數的統計結果:
顯示global級的所有參數的統計結果:
第二步:定位執行效率低的SQL語句
可以通過以下兩種方式定位執行效率低的sql語句
1)慢查詢日志:用--log-slow-querles[=file_name]選項啟動時,mysql寫一個包含所有執行時間超過long_query_time秒的sql語句的日志文件。
2)show processlist:慢日志查詢在查詢結束后才記錄,所以在應用反映執行效率出現問題的時候查詢慢查詢日志並不能定位問題,可以使用show processlist命令查看當前mysql在進行的線程,包括線程的狀態,是否鎖表等,可以實時地查看sql的執行情況,同時對一些鎖表操作進行優化。
第三步:explain分析執行計划
通過以上步驟查詢到效率低的sql語句后,可以通過explain或者desc命令獲取mysql如何執行select語句的信息,包括在select語句執行過程中表如何連接和連接的順序。
查詢sql語句的執行計划:
id:id相同表示加載表的順序是從上到下;id不同id值越大,優先級越高,越先被執行;id有相同也有不同,id相同則從上到下順序執行,id不同則id值越大越先被執行。
select_type:表示select的類型,有如下的常見取值:
table:展示這一行的數據是關於哪一張表的
type:顯示的是訪問類型,是較為重要的一個指標,可取值為:
key:
rows:掃描行的數量
extra:其他的額外的執行計划信息,在該列展示
第四步:show profile分析sql
Mysql從5.0.37版本開始增加了對show profiles 和show profile語句的支持,show profiles能夠在做sql優化時幫助我們了解時間都耗費到哪里去了。
通過select @@profiling命令查看當前mysql是否開啟profile:(1表示已經開啟,可以通過set profiling=1命令開啟,set profiling=0關閉)
隨便執行幾條sql語句:
再通過show profiles命令查看sql語句執行的耗時:
通過show profile for query query_id命令查看某條sql在執行過程中每個線程的狀態和消耗的時間
注意:Sending data 狀態便是mysql線程開始訪問數據行並把結果返回給客戶端,而不僅僅是返回給客戶端,由於在Sending data狀態下,mysql線程往往要坐大量的磁盤讀取操作,所以經常是整個查詢中耗時最長的狀態。
在獲取到最消耗時間的線程狀態之后,mysql支持進一步選擇all、cpu、block lo、context switch、page faults等明細類型查看mysql在使用什么資源上耗費了過高的時間,例如,選擇查看cpu的耗費時間:
第五步:trace分析優化器執行計划
mysql5.6提供了對sql的跟蹤trace,通過trace文件能夠進一步了解為什么優化器選擇A計划而不是選擇B計划
打開trace。設置格式為json並設置trace最大能夠使用的內存大熊啊,避免解析過程因為內存過小而不能夠完整展示。
在執行完sql語句后,檢查 information_schema.optimizer_trace就可以知道mysql是如何執行sql的。