性能測試四十一:sql案例之慢sql配置、執行計劃和索引
MYSQL 慢查詢使用方法
MYSQL慢查詢介紹
分析MySQL語句查詢性能的問題時候,可以在MySQL記錄中查詢超過指定時間的語句,我們將超過指定時間的SQL語句查詢稱為“慢查詢”。MYSQL自帶的慢查詢分析工具mysqldumpslow可對慢查詢日誌進行分析:主要功能是, 統計sql的執行信息,其中包括 :
出現次數(Count),
執行最長時間(Time),
累計總耗費時間(Time),
等待鎖的時間(Lock),
發送給客戶端的行總數(Rows),
掃描的行總數(Rows),
用戶以及sql語句本身(抽象了一下格式, 比如 limit 1, 20 用 limit N,N 表示).
案例:慢sql
先確定項目指向的數據庫是對的
問題接口:http://localhost:8080/PerfTeach/SlowQuery?cardNO=10001
由於數據庫裏面是card_no,而代碼裏面是cardNO,所以要改一下數據庫裏面的字段名
修改
訪問一下:http://localhost:8080/PerfTeach/SlowQuery?cardNO=10001,和數據庫裏的一樣
在jmeter裏面造一個10000--20000的隨機數函數
監控開起來
運行jmeter,用10個並發,跑600秒
TPS很低
響應時間很長
CPU高
mysql進程占了89.9%的cpu使用率
所以,可以確定是mysql這塊有問題,而這種問題一般都是sql寫的不好造成的
1、 開啟慢SQL的配置
1.1 LIUNX 系統 在mysql配置文件my.cnf中(文件最後)增加
slow_query_log:這是一個布爾型變量,默認為真。沒有這變量,數據庫不會打印慢查詢的日誌。
slow_query_log_file=/usr/local/mysql/data/zhoucentos-slow.log:(指定日誌文件存放位置(安裝mysql的目錄),可以為空,系統會給一個缺省的文件hostName-slow.log)
long_query_time=0.1:(記錄超過的時間,默認為10s),與DBA溝通,性能測試分析問題時可以將該值設為0.1即100毫秒,這樣分析的粒度更詳細。
重啟mysql
1.2 Windows下配置:
在my.ini的[mysqld]添加如下語句:
log-slow-queries = E:\web\mysql\log\mysqlslowquery.log
long_query_time = 0.1(其他參數如上)
註: 配置完成後,重新mysql服務配置才能生效。
2、 慢查詢開啟與關閉
2.1 配置完成,連接數據庫檢查慢查詢日誌是否開啟:
命令如下:mysql> show variables like ‘%slow_query_log%‘;
壓一下,看看有沒有數據寫進去,從172,變成了124800,使用-h查看:122K
2.2 如果沒有打開,請開啟,slow_query_log,以下方法是一次性的,只要重啟mysql就會恢復到原樣
開啟命令:mysql> set @@global.slow_query_log = on;
關閉命令:mysql> set @@global.slow_query_log = off;
2.3 再次檢查是否開啟成功
mysql> show variables like ‘%slow_query_log%‘;
2.4 檢查目錄中是否生成文件
/mysql目錄下是否存在mysql_slow.log
[root@localhost mysql]# ls -l mysql_slow.log
3、 慢查詢日誌分析
3.1 Linux系統:
使用mysql自帶命令mysqldumpslow查看(需在mysql/bin目錄下執行,因為mysqldumpslow在bin目錄下)
常用命令,通過 ./mysqldumpslow -help查看
-s,是order的排序,主要有 c,t,l,r和ac,at,al,ar,分別是按照query次數,時間,lock的時間和返回的記錄數來排序
-a,倒序排列
-t,是top n的意思,即為返回前面多少條的數據
-g,後邊可以寫一個正則匹配模式,大小寫不敏感的
例如:
./mysqldumpslow -s c -t 20 host-slow.log:訪問次數最多的20個sql語句
./mysqldumpslow -s r -t 20 host-slow.log:返回記錄集最多的20個sql
./mysqldumpslow -t 10 -s t -g “left join” host-slow.log這個是按照時間返回前10條裏面含有左連接的sql語句。
./mysqldumpslow -s at -t 50 host-slow.log 顯示出耗時最長的50個SQL語句的執行信息(此方法最常用)
總共執行了602次,平均執行390毫秒,和jmeter統計出來的平均響應時間差不多了,所以,時間都耗在執行sql上面了
由於這裏數據量不夠,所以找了個項目中的圖
以Count: 32 Time=0.26s (8s) Lock=0.00s (0s) Rows=10.0 (320), wos_20120719[wos_20120719]@2host 為例:
Count: 32 該SQL總共執行32次
Time = 0.26s (8s) 平均每次執行該SQL耗時0.26秒,總共耗時32(次)*0.26(秒)=8秒。
Lock=0.00s(0s) lock時間0秒
Rows =10.0(320) 每次執行SQL影響數據庫表中的10行記錄,總共影響 10(行)*32(次)=320行記錄
執行計劃
在sql語句前加上explain,可以分析這條sql語句的執行情況:explain select * from teacher where cardNO=10000
select_type:
SIMPLE:簡單查詢
Type列可能的值(以下按效率降序排列):
Const:表中只有一個匹配行,用到primary key或unique key (性能最好)
Eq_ref:唯一性索引掃描,key的所有部分被連接聯接查詢使用,且key是unique或primary key
ref:非唯一性索引掃描,或只使用了聯合索引的最左前綴
Range:索引範圍掃描,在索引列上進行給定範圍內的檢索,如between,in(1,100)
Index:遍歷索引...(類似於在字典上找字)
All:全表掃描(沒有用索引,直接從表裏面第一條找到最後一條(即使在前面或中間已經找到數據),所以項目中一般禁止使用select*和全表掃描)
所以上面就運行那條簡單的sql,確很費cpu,就是因為在進行全表掃描
在工作中,一般有以下3種情況會造成sql效率低:
1.庫裏面沒有加索引
2.加了索引,但是索引加的不合理
3.索引加的合理,但是sql寫的不合理
一般,一個表裏面,最多加3/4個索引,不能再多,否則就是表設計的不合理
上面那個情況就是應為沒有加索引,所以,加個索引看看,
一般加索引,就看where條件的字段,用這些字段來當索引,這條sql就一個字段:cardNO
壓一下看看
TPS從剛才的20多變成了300多,提升了15倍左右
響應時間:從剛才的400左右,降到30左右
TOP命令查看,mysql只占了22.2%,一般項目中就應該是tomcat占比最高,應為它要處理業務邏輯
由於壓測還在進行中,所以可以把慢查詢的日誌清空後再看看還有沒有慢查詢
文件大小都是0了,沒有往文件裏面寫入內容了
3.2 Windows系統:
當你是第一次開啟mysql的慢查詢,會在你指定的目錄下創建這個記錄文件,本文就是mysqlslowquery.log,這個文件的內容大致如下(第一次開啟MYSQL慢查詢的情況下)
E:\web\mysql\bin\mysqld, Version: 5.4.3-beta-community-log (MySQL Community Server (GPL)). started with:
TCP Port: 3306, Named Pipe: (null)
Time Id Command Argument
可以通過如下的命令來查看慢查詢的記錄數:
mysql> show global status like ‘%slow%’;
+———————+——-+
| Variable_name | Value |
+———————+——-+
| Slow_launch_threads | 0 |
| Slow_queries | 0 |
+———————+——-+
性能測試四十一:sql案例之慢sql配置、執行計劃和索引