天天看點

mysql case預設_MySQL查詢優化(3)-慢查詢開啟、日志分析

說明

  • Mysql的查詢訊日志是Mysql提供的一種日志記錄,它用來記錄在Mysql中響應時間超過門檻值的語句
  • 具體指運作時間超過long_query_time值得SQL,則會被記錄到慢查詢日志中。long_query_time的預設為10,意識是運作10秒以上的語句。
  • 由它來看那些SQL語句超出了我們的最大忍耐值,比如一條SQL執行超過了5秒,我們就算慢查詢,我們就可以結合Explain進行分析。

檢視是否開啟及如何開啟

預設Mysql沒有開啟慢查詢,需要我們說動設定這個參數。當然,如果不是調優需要的話,一般不建議開啟該參數,因為開啟慢查詢日志會或多或少帶來一定的性能影響。慢查詢日志支援将日志寫入檔案。

進入mysql終端檢視是否開啟(我這裡都是自己改過的)

mysql
           

上面查詢結果第一行,這裡是開啟的,第二行是預設查詢路徑檔案名。

mysql> set global slow_query_log = 0|1; //設定開啟或者關閉,0為關閉,1為開啟
           

如果使用set global slow_query_log 指令開啟慢查詢日志,隻對

目前資料庫生效

,如果Mysql重新開機後則會失效。

補充:如果通過終端指令設定的話,再查詢是看不到修改結果的,需要新開啟一個視窗檢視即可。

如果要永久生效,必須修改my.cnf配置檔案(其他系統變量也是如此),

修改my.cnf檔案,[mysqld]下增加和修改參數slow_query_log和slow_query_log_file後,然後重新開機MySQL伺服器,也即将如下兩行配置進my.cnf檔案

slow_query_log = 1

slow_query_log_file = /data/mysql/mysql-slow.log

[mysqld]
slow_query_log = 1
long_query_time = 1
slow_query_log_file = /data/mysql/mysql-slow.log
           

關于慢查詢的參數slow_query_log_file,它指定慢查詢日志檔案的存放路徑,

系統預設會給一個預設的host_name_show.log

(如果沒有指定參數slow_query_log_file的話)。

那麼開啟了慢日志後,怎麼樣的SQL才會記錄到慢查詢當中呢?

  • 這個是由參數long_query_time控制,預設情況下long_query_time的值是10秒。
  • 指令SHOW VARIABLES LIKE 'long_query_time';
mysql> show variables like 'long_query_time';
+-----------------+----------+
| Variable_name   | Value    |
+-----------------+----------+
| long_query_time | 10.00000 |
+-----------------+----------+
           

可以使用指令修改,也可以在my.cnf參數裡面修改,修改完記得習慣性重新開機服務。還是那句話,不建議生産環境開啟。

mysql
           

假如SQL運作時間剛好等于long_query_time的情況,并不會被記錄下來,也就是說,在Mysql源碼裡是

判斷大于long_query_time,而非大于等于。

Case

  • 檢視目前多少秒算慢:SHOW VARIABLES LIKE 'long_query_time%';
  • 設定慢的阙值時間:set global long_query_time=3;
mysql case預設_MySQL查詢優化(3)-慢查詢開啟、日志分析
  • 為什麼設定後看不出變化:
  1. 需要重新連接配接或新開一個回話才能看到修改值; SHOW VARIABLES LIKE 'long_query_time%';
  2. SHOW GLOBAL VARIABLES LIKE 'long_query_time%';
mysql case預設_MySQL查詢優化(3)-慢查詢開啟、日志分析
  • 記錄慢SQL并後續分析:select sleep(4);

檢視慢查詢日志檔案

# cat /data/mysql/mysql-slow.log 
# 
# select sleep(5);
# Time: 2018-01-20T18:10:24.443517Z
# [email protected]: root[root] @ localhost [] Id: 3
# Query_time: 5.000564 Lock_time: 0.000000 Rows_sent: 1 Rows_examined: 0
use test_db;   #使用的資料庫
SET timestamp=1524276624;  #時間戳
select sleep(5); #問題SQL
           

以上資訊包括實際查詢時間5.000564秒,時間戳timestamp=1524276624,還有庫test_db,出問題的SQL。

  • 檢視目前系統中多少條滿記錄:show global status like '%Slow_queries%';
mysql> show global status like '%Slow_queries%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Slow_queries  | 1     |
+---------------+-------+
1 row in set (0.03 sec)
           

可以作為系統健康檢查度來查詢。(什麼意思:如果系統裡面充滿了大量的慢SQL,都超過阙值,這時系統就需要及時優化)

配置版
show_query_log = 1;
show_query_log_file=/var/lib/mysql/mysql_slow.log
log_query_time=3;
log_output=FILE
           

mysqldumpslow用法講解

  • 在生産環境中,如果要手動分析日志,查找、分析SQL,顯然是一個體力活,MySQL提供了日志分析工具mysqldumpslow。

上面測試的慢查詢SQL隻有一條,假如在實際的生産環境中,慢查詢SQL遠遠高于測試的數量,十幾條甚至幾十條,假如幾條慢查詢出現的頻率很高,我們能做到根據輕重優先級來分析并排除那是不是更好?那麼就用到了mysqldumpslow

[[email protected] mysql]# mysqldumpslow --help   ----------------------------------------------------//執行指令
Usage: mysqldumpslow [ OPTS... ] [ LOGS... ]

Parse and summarize the MySQL slow query log. Options are

  --verbose    verbose
  --debug      debug
  --help       write this text to standard output

  -v           verbose
  -d           debug
  -s ORDER     what to sort by (al, at, ar, c, l, r, t), 'at' is default
                al: average lock time
                ar: average rows sent
                at: average query time
                 c: count
                 l: lock time
                 r: rows sent
                 t: query time  
  -r           reverse the sort order (largest last instead of first)
  -t NUM       just show the top n queries
  -a           don't abstract all numbers to N and strings to 'S'
  -n NUM       abstract numbers with at least n digits within names
  -g PATTERN   grep: only consider stmts that include this string
  -h HOSTNAME  hostname of db server for *-slow.log filename (can be wildcard),
               default is '*', i.e. match all
  -i NAME      name of server instance (if using mysql.server startup script)
  -l           don't subtract lock time from total time
           

s:是表示按照何種方式排序

c:通路次數

i:鎖定時間

r:傳回記錄

t:查詢時間

al:平均鎖定時間

ar:平均傳回記錄數

at:平均查詢時間

t:即為傳回前面多少條資料

g:後邊搭配一個正則比對模式,大小寫不敏感

mysqldumpslow -s r -t 10 /data/mysql/mysql-slow.log  //得到傳回記錄集最多的10個SQL
mysqldumpslow -s c -t 10 /data/mysql/mysql-slow.log //得到通路次數最多的10個SQL 
mysqldumpslow -s t -t 10 -g "left join" /data/mysql/mysql-slow.log  //得到按照時間排序的前10條裡面含有做了連接配接的查詢SQL
mysqldumpslow -s r -t 10 /data/mysql/mysql-slow.log | more  //另外建議在使用這些指令時結合|和more使用,否則有可能出現爆屏情況
           

OK~既然學習了,就運用到實際工作中吧~