背景
? ? ? ?由于系統(tǒng)在生產(chǎn)環(huán)境運(yùn)行了一段時間,發(fā)現(xiàn)系統(tǒng)超時的接口的請求越來越多,通過服務(wù)器的日志發(fā)現(xiàn)同樣的接口,有時候會超過2s, ?有時候又幾百毫秒就完成,通過把 接口的 sql拿出來分析執(zhí)行,工作量有點(diǎn)大。還好之前mysql打開了慢日志的開關(guān),通過對mysql的慢日志進(jìn)行分析,可以解決大部分的問題。
慢日志設(shè)置
1 連接數(shù)據(jù)庫
? ? mysql -h127.0.0.1 -P3306-uroot -pxxxxx;
2 ?選擇數(shù)據(jù)庫
? ? ?use mysql;
3 ?查看慢日志的設(shè)置
? ? show variables like '%query%';
? ? long_query_time:單位秒,腳本運(yùn)行的時間操作這個設(shè)置為慢查詢
? ?slow_query_log: 慢日志的開關(guān)
? ?slow_query_log_file:慢日志保存的路徑

慢日志分析
1 慢日志下載
通過sz 命令把慢日志下載到本地進(jìn)行分析
2慢日志的格式說明
# Time: 150401 11:24:27
# User@Host: root[root] @ localhost [127.0.0.1] Id: 7
# Query_time: 0.034002 Lock_time: 0.000000 Rows_sent: 3 Rows_examined: 3
use libu;
SET timestamp=1427858667;
select * from aaa;
分析如下:
(1) Time: 執(zhí)行時間
(2) User@Host: 執(zhí)行sql的主機(jī)信息
(3) Query_time: sql的執(zhí)行信息,
? ? ? Lock_time: 鎖定時間,?
? ? ? Rows_sent: 發(fā)送(結(jié)果)行數(shù),
? ? ? Rows_examined:掃描的行數(shù)
(4) timestamp: 執(zhí)行時間
(5) select * from aaa; : 查詢語句內(nèi)容
3慢日志分析的命令
-s, 是表示按照何種方式排序,
? ? ? ?c: 訪問計數(shù)
? ? ? ?l: 鎖定時間
? ? ? ?r: 返回記錄
? ? ? ?t: 查詢時間
? ? ? ?al:平均鎖定時間
? ? ? ?ar:平均返回記錄數(shù)
? ? ? at:平均查詢時間
-t, 是top n的意思,即為返回前面多少條的數(shù)據(jù);
-g, 后邊可以寫一個正則匹配模式,大小寫不敏感的;
比如
得到返回記錄集最多的10個SQL。
mysqldumpslow -s r -t 10 /database/mysql/mysql06_slow.log
得到訪問次數(shù)最多的10個SQL
mysqldumpslow -s c -t 10 /database/mysql/mysql06_slow.log
得到按照時間排序的前10條里面含有左連接的查詢語句。
mysqldumpslow -s t -t 10 -g “l(fā)eft join” /database/mysql/mysql06_slow.log
另外建議在使用這些命令時結(jié)合 | 和more 使用 ,否則有可能出現(xiàn)刷屏的情況。
mysqldumpslow -s r -t 20 /mysqldata/mysql/mysql06-slow.log | more
4數(shù)據(jù)分析結(jié)果
通過上述的命令,查找到查詢時間比較長的 sql,找到對應(yīng)的業(yè)務(wù)進(jìn)行優(yōu)化,優(yōu)化的思路:
1 通過條件的關(guān)聯(lián)減少查詢的數(shù)據(jù)量
2通過建立索引加快查詢
3通過業(yè)務(wù)手段減少數(shù)據(jù)量的查詢
? ?例如:一般的系統(tǒng)都有分頁功能的查詢,需要查詢到請求的總數(shù)量,由于目前需要顯示總的數(shù)量,沒有辦法避免不查詢總的數(shù)量,這個查詢會隨著數(shù)據(jù)量的增多而變慢,只能通過業(yè)務(wù)手段進(jìn)行處理,例如只是查詢某個時間段的數(shù)據(jù),而不是查詢所有的數(shù)據(jù)的數(shù)量。