1. 程式人生 > >性能測試四十一:sql案例之慢sql配置、執行計劃和索引

性能測試四十一:sql案例之慢sql配置、執行計劃和索引

xpl 通過 數據庫 data 設計 增加 應該 windows 情況下

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毫秒,這樣分析的粒度更詳細。

  備選 :log-queries-not-using-indexes (log下來沒有使用索引的query,可以根據情況決定是否開啟)。log-long-format (如果設置了,所有沒有使用索引的查詢也將被記錄)

技術分享圖片

技術分享圖片

重啟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配置、執行計劃和索引