mysql 性能查看_MySQL查询性能问题排查
Mysql數據庫的性能問題排查是十分復雜的,具體方法視場景而定,這里只做大致思路分析。
1. 整體考慮導致查詢性能低下的各種因素
導致SQL查詢變慢的原因是多元化的,在遇到問題時首先要有一個全方位的思考:
網絡問題導致
應用層導致
代碼中是否有不合理的查詢
緩存失效導致查詢風暴耗盡磁盤資源
MySQL服務器性能導致
是否是由服務器上其它任務占用資源過多導致資源不足
磁盤IO的讀寫速率是否太慢
MySQL寫操作頻繁
MySQL寫入大量數據到磁盤
MySQL寫入大量日志到磁盤
MySQL寫入大量排序文件到磁盤
MySQL寫入大量臨時表到磁盤
并發度超過某個閥值時,InnoDB的擴展性限制導致查詢計劃的優化需要很長時間
InnoDB瘋狂刷新臟頁導致內部嚴重阻塞
庫表結構設計不合理
SQL語句設計有問題或效率低
索引實際沒有正常使用
2. 剖析MySQL查詢
1. 剖析服務器負載
捕獲查詢到查詢日志文件中
使用慢查詢日志
5.0版本以前慢查詢日志是秒級別,5.1版本以后以達到微秒級。
可以通過設置long_query_time=0來捕獲所有查詢。
如果長期開啟慢查詢日志,要部署日志輪轉(log rotation)工具。
當因權限不足等原因無法在服務器上記錄查詢時可使用pt-query-digest工具
通過--processlist選項不斷查看SHOW FULL PROCESSLIST的輸出,記錄查詢第一次出現的時間和消失的時間。(精度差)
通過抓取TCP網絡包,然后根據MySQL客戶端/服務端通信協議進行解析。(精度高)
通過tcpdump將網絡包數據保存到磁盤。
使用pt-query-digest的--type=tcpdump選項解析并分析查詢。
分析查詢日志
使用pt-query-digist工具生成剖析報告(請勿直接打開整個慢查詢日志進行分析,避免浪費時間)
報告中V/M列提供了方差均之比的詳細數據,數值高的查詢對應的執行時間的變化較大,這類查詢通常都值得去優化。
pt-query-digest指定--explain選項,輸出中會增加一列簡要描述查詢的執行計劃。通過觀察V/M和執行計劃列,可以更容易識別出性能低下需要優化的查詢。
可以通過--limit和--outliers選項指定工具顯示更多查詢的詳細信息。
可以通過查詢的ID或排名匹配剖析統計和查詢的詳細報告。
2. 剖析單條查詢
? 在定位到需要優化的單條查詢后,可以根據此查詢獲得更多信息。以下是一些剖析方法:
使用SHOW PROFILES;
5.1版本引入,默認禁用,可以會話級別開啟:SET profiling = 1;
使用SHOW PROFILE FOR QUERY #Query_ID;通過Query_ID打印一條查詢語句的詳細查詢報告,其中可以看到查詢執行的每個步驟及其花費的時間。(按執行順序排序,無法ORDER BY)。
直接查詢INFORMATION_SCHEMA中對應的表,可以按需要的格式化輸出:
SET @query_id = #Query_ID;
SELECT STATE, SUM(DURATION) AS Total_R,
ROUND(
100 * SUM(DURATION) /
(
SELECT SUM(DURATION)
FROM INFORMATION_SCHEMA.PROFILING
WHERE QUERY_ID = @query_id
), 2) AS Pct_R,
COUNT(*) AS Calls,
SUM(DURATION) / COUNT(*) AS "R/Call",
FROM INFORMATION_SCHEMA.PROFILING
WHERE QUERY_ID = @query_id
GROUP BY STATE
ORDER BY Total_R DESC;
通過分析結果得到查詢時間太長可能存在的原因:
花大量時間將數據復制到臨時表。
考慮如何改寫查詢以避免使用臨時表。
提升臨時表的使用效率。
發送數據(Sending Data)花費時間太多。
使用SHOW STATUS;
此命令返回一些服務器級別和會話級別的計數器。
SHOW GLOBAL STATUS返回服務器級別的從服務器啟動開始計算的查詢次數統計。
很多有用的計數器:Create_tmp_disk_tables磁盤臨時表、Create_tmp_tables臨時表、Handler_read_rnd_next沒有用到索引的讀操作等。
EXPLAIN是通過估計得到的結果,無法確認臨時表是否是磁盤表。(磁盤表和內存表性能差異很大)
使用慢查詢日志
執行show variables like 'slow_query_log';查看慢查詢日志是否開啟。
若沒有開啟找到my.cnf,添加如下內容sudo vim /usr/local/mysql/my.cnf
log_output=file
slow_query_log=on
slow_query_log_file = /tmp/mysql-slow.log
log_queries_not_using_indexes=on
long_query_time = 1
重啟MySQL并執行以下操作查看:
show variables like 'slow_query_log';
show variables like '%quer%';
先使用pt_query_digest生成的報告進行分析,然后有目標地使用慢查詢日志。
通過字節量偏移值byte 123直接跳轉到日志對應部分:
tail -c +123 /tmp/mysql-slow.log | head -n100
使用Performance Schema
5.5版本新增的表但還不支持查詢級別的剖析信息。
主要為了測量當為提升服務器性能而修改MySQL源代碼時使用。
使用USER_STATISTICS表:
通過這些表可以對數據庫活動進行測量和審計
可以強制執行使用策略
對于共享主機環境這樣的多租戶環境也同樣有用
查看這些表:
SHOW TABLES FROM INFORMATION_SCHEMA LIKE '%_STATISTICS';
一些有用的查詢:
可以查找使用最多或使用最少的表和索引,通過讀取次數或更新次數,或兩者一起排序。
可以查找從未使用的索引。
可以查看復制用戶的CONNECTED_TIME和BUSY_TIME,以確認是否會很難跟上主庫的進度。
3. 診斷間接性問題
盡量不要使用試錯的方式解決問題,而是應該在有問題發生的地方通過觀察資源的使用情況并盡可能測量數據。
1. 確定是單條查詢問題還是服務器問題
若果服務器上所有程序都突然變慢,又突然變好,每一條查詢也都變慢了,那么慢查詢可能就不一定是原因。
老版本MySQL對高配置服務器(多CPU)支持不好,新版本相對好些。此時可通過升級MySQL版本來解決問題。
下面是解決間接性問題的方法和工具:
以較高頻率執行SHOW GLOBAL STATUS
以較高頻率執行SHOW PROCESSLIST
使用查詢日志
用gnuplot或R等繪圖工具將結果繪制成圖形幫助分析
2. 捕獲診斷數據
當出現間接性問題時,需要盡可能多地收集數據,而不只是出現問題時的數據。
診斷觸發器
是問題出現時能捕獲數據的基礎。
誤報和漏檢可能導致無法達到預期的結果。
監控服務器,當達到觸發條件時能收集數據的工具:pt-stalk
確定需要收集什么樣的數據
在需要的時間段內盡可能地收集所有能收集的數據。
執行時間包括工作時間和等待時間。
用于服務器內部診斷的重要工具oprofile。
可以使用strace剖析服務器的系統調用。(生產環境中有一定風險)
有一些不可預期性
開銷大
使用的是實際時間
對mysqld這樣有大量線程場景會產生一些副作用,導致mysqld運行非常慢
可以使用tcpdump剖析查詢。
可以使用GDB的堆棧跟蹤進行對等分析。(具有侵入性,會暫時造成服務器停頓)
可以使用SHOW PROCESSLIST和SHOW INNODB STATUS的快照信息觀察線程和事務的狀態進行等待分析。
可以使用pt-collect工具收集數據,一般通過pt-stalk調用。
3. 解釋結果數據
如果已經正確設置好觸發條件,并且長時間運行pt-stalk,則只需要等待足夠長的時間來捕獲幾次問題,就能得到大量數據進行篩選。
建議根據兩個目的來查看:
檢查問題是否真的發生了。
是否有非常明顯的跳躍性變化。
查看異常的查詢和事務的行為,以及異常服務器內部行為通常都是最有效的。通過抓取TCP流量或SHOW PROCESSLIST輸出,可以獲得查詢和事務出現的地方,從而知道用戶對數據庫進行了什么操作。服務器內部行為可在oprofile或者gdb的輸出中看到。
查看異常的查詢和事務的行為,可以顯示是否由于使用服務器的方式導致的問題:
性能低下的SQL查詢
使用不當的索引
設計糟糕的數據庫邏輯架構
通過服務器的內部行為:
可以清楚服務器是否有BUG
內部的性能和擴展性是否有問題
pt-mysql-summary和pt-summary這兩個工具會輸出MySQL的狀態和配置信息,以及操作系統和硬件信息。
pt-sift是一款快速檢查收集到的樣本數據的工具。
gdb的堆棧追蹤是重要的等待分析的性能瓶頸分析工具:
需要自下而上來看。
將很多信息聚合在一起來看。
窮人剖析器poor man's profiler:
pt-pmp
如何高性能的使用MySQL呢?
1. 設計最優的庫表結構
2. 建立最好的索引并實際應用
3. 設計合理的SQL
總結
以上是生活随笔為你收集整理的mysql 性能查看_MySQL查询性能问题排查的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql having实例_Mysql
- 下一篇: java基础教程传值_Java基础——方