mysql 慢查詢,你操作的對嗎?

 mysql 慢查詢 實戰-詳細講解。

Hello,大家好。我是公衆號“八點半技術站”的小編-Bruce.D。

今天是週一(2020-03-23),我國有句俗語說的好 “一日之計在於晨” ,因此我分享給大家的是 「mysql 模塊」- mysql 慢查詢。想必mysql 慢查詢在我們開發中也是必須可少的一環吧,畢竟你聽到 “慢查詢” 這幾個字,想必也很熟悉吧。那麼接下來,就讓我來爲大家進行詳細的分析

01

概念方面

MySQL 慢查詢,全稱 慢查詢日誌 ,它是 MySQL 提供的一種日誌記錄,用了記錄在 MySQL 中響應時間超過閾值的語句。

具體環境中,如果運行時間超過 long_query_time 值的 sql 語句,則會被記錄到慢查詢日誌中。

通常 long_query_time 的默認值爲10,這也代表意思是運行10秒以上的 sql 語句時間。默認情況下,MySQL 是不會自動啓動慢查詢日誌的,需要我們手動來設置這個參數。

那麼當然,如果我們不是用來將項目進行調優的話,一般不建議啓動該參數,因爲開啓後,對於慢查詢日誌的性能多少會帶來影響。

:慢查詢日誌支持將日誌記錄寫入文件和數據庫表

02


參數方面

slow_query_log:是否開啓慢查詢日誌,1/開啓,0/關閉。

log-slow-queries | slow-query-log-file:5.6以下 和 5.6以上版本版本 MySQL 數據庫慢查詢日誌存儲路徑。可以不設置該參數,系統則會默認給一個缺省的文件host_name-slow.log

long_query_time:慢查詢閾值,當查詢時間多於設定的閾值時,記錄日誌。

log_queries_not_using_indexes:未使用索引的查詢也被記錄到慢查詢日誌中(可選項)。

log_output:日誌存儲方式。log_output='FILE' 表示將日誌存入文件,默認值是 'FILE' ;log_output='TABLE' 表示將日誌存入數據庫。

03


配置方面

配置從以下幾個小節分析給大家

第一小節:slow_query_log

默認情況下 slow_query_log 的值爲OFF,表示慢查詢日誌是禁用的,可以通過設置 slow_query_log 的值來開啓,如下所示:

mysql> show variables  like '%slow_query_log%';
 +---------------------+-----------------------------------------------+
 | Variable_name       | Value                                         |
 +---------------------+-----------------------------------------------+
 | slow_query_log      | OFF                                           |
 | slow_query_log_file | /home/WDPM/MysqlData/mysql/DB-Server-slow.log |
 +---------------------+-----------------------------------------------+
 2 rows in set (0.00 sec)


mysql> set global slow_query_log=1;
 Query OK, 0 rows affected (0.09 sec)

使用 set global slow_query_log=1 開啓了慢查詢日誌只對當前數據庫生效,MySQL重啓後則會失效。

如果要永久生效,就必須修改配置文件 my.cnf 。

my.cnf要增加或修改參數 slow_query_log slow_query_log_file,如下所示:

slow_query_log = 1
slow_query_log_file = /tmp/mysql_slow.log

然後重啓 MySQL 服務器即可。

第二小節:slow_query_log_file

這個參數用於指定慢查詢日誌的存放路徑,缺省情況是host_name-slow.log文件

mysql> show variables like 'slow_query_log_file';
 +---------------------+-----------------------------------------------+
 | Variable_name       | Value                                         |
 +---------------------+-----------------------------------------------+
 | slow_query_log_file | /home/WDPM/MysqlData/mysql/DB-Server-slow.log |
 +---------------------+-----------------------------------------------+
 1 row in set (0.00 sec)

第三小節:long_query_time

開啓了慢查詢日誌後,什麼樣的SQL纔會記錄到慢查詢日誌裏面呢?

這個是由參數 long_query_time 控制,默認情況下 long_query_time的值爲10秒,可以使用命令修改,也可以在 my.cnf 參數裏面修改。

關於運行時間正好等於 long_query_time 的情況,並不會被記錄下來。

也就是說,在 mysql 源碼裏是判斷大於 long_query_time,而非大於等於。

從MySQL 5.1開始,long_query_time 開始以微秒記錄SQL語句運行時間,之前僅用秒爲單位記錄。

如果記錄到表裏面,只會記錄整數部分,不會記錄微秒部分。

mysql> show variables like 'long_query_time%';
 +-----------------+-----------+
 | Variable_name   | Value     |
 +-----------------+-----------+
 | long_query_time | 10.000000 |
 +-----------------+-----------+
 1 row in set (0.00 sec)


mysql> set global long_query_time=4;
 Query OK, 0 rows affected (0.00 sec)


mysql> show variables like 'long_query_time';
 +-----------------+-----------+
 | Variable_name   | Value     |
 +-----------------+-----------+
 | long_query_time | 10.000000 |
 +-----------------+-----------+
 1 row in set (0.00 sec)

如上所示,我修改了變量long_query_time,但是查詢變量long_query_time的值還是10,難道沒有修改到呢?

注意:使用命令 set global long_query_time=4修改後,需要重新連接或新開一個會話才能看到修改值。

用 show variables like 'long_query_time' 查看是當前會話的變量值。

也可以不用重新連接會話,而是用show global variables like 'long_query_time'。

第四小節:log_output

log_output 參數指定日誌的存儲方式。

log_output='FILE' 表示將日誌存入文件,默認值也是 'FILE' 。

log_output='TABLE' 表示將日誌存入數據庫,這樣日誌信息就會被寫入到mysql.slow_log 表中。

同時也支持兩種日誌存儲方式,配置的時候以逗號隔開即可,如:log_output='FILE,TABLE'

日誌記錄到系統的專用日誌表中,要比記錄到文件耗費更多的系統資源。

因此對於需要啓用慢查詢日誌,又需要能夠獲得更高的系統性能,那麼建議優先記錄到文件。

mysql> show variables like '%log_output%';
 +---------------+-------+
 | Variable_name | Value |
 +---------------+-------+
 | log_output    | FILE  |
 +---------------+-------+
 1 row in set (0.00 sec)
 
mysql> set global log_output='TABLE';
 Query OK, 0 rows affected (0.00 sec)


mysql> show variables like '%log_output%';
 +---------------+-------+
 | Variable_name | Value |
 +---------------+-------+
 | log_output    | TABLE |
 +---------------+-------+
 1 row in set (0.00 sec)


mysql> select sleep(5) ;
 +----------+
 | sleep(5) |
 +----------+
 |        0 |
 +----------+
 1 row in set (5.00 sec)


mysql>


mysql> select * from mysql.slow_log;
 +---------------------+---------------------------+------------+-----------+-----------+---------------+----+----------------+-----------+-----------+-----------------+-----------+
 | start_time          | user_host                 | query_time | lock_time | rows_sent | rows_examined | db | last_insert_id | insert_id | server_id | sql_text        | thread_id |
 +---------------------+---------------------------+------------+-----------+-----------+---------------+----+----------------+-----------+-----------+-----------------+-----------+
 | 2016-06-16 17:37:53 | root[root] @ localhost [] | 00:00:03   | 00:00:00  |         1 |             0 |    |              0 |         0 |         1 | select sleep(3) |         5 |
 | 2016-06-16 21:45:23 | root[root] @ localhost [] | 00:00:05   | 00:00:00  |         1 |             0 |    |              0 |         0 |         1 | select sleep(5) |         2 |
 +---------------------+---------------------------+------------+-----------+-----------+---------------+----+----------------+-----------+-----------+-----------------+-----------+
 2 rows in set (0.00 sec)


第五小節:log-queries-not-using-indexes

該系統變量指定未使用索引的查詢也被記錄到慢查詢日誌中(可選項)。

如果是進行調優的話,建議開啓這個選項。

另外,開啓了這個參數,其實使用 full index scan 的 SQL 也會被記錄到慢查詢日誌。

mysql> show variables like 'log_queries_not_using_indexes';
 +-------------------------------+-------+
 | Variable_name                 | Value |
 +-------------------------------+-------+
 | log_queries_not_using_indexes | OFF   |
 +-------------------------------+-------+
 1 row in set (0.00 sec)


mysql> set global log_queries_not_using_indexes=1;
 Query OK, 0 rows affected (0.00 sec)


mysql> show variables like 'log_queries_not_using_indexes';
 +-------------------------------+-------+
 | Variable_name                 | Value |
 +-------------------------------+-------+
 | log_queries_not_using_indexes | ON    |
 +-------------------------------+-------+
 1 row in set (0.00 sec)

第六小節:log_slow_admin_statements

這個系統變量表示,是否將慢管理語句例如 ANALYZE TABLE和ALTER TABLE等記入慢查詢日誌。

mysql> show variables like 'log_slow_admin_statements';
 +---------------------------+-------+
 | Variable_name             | Value |
 +---------------------------+-------+
 | log_slow_admin_statements | OFF   |
 +---------------------------+-------+
 1 row in set (0.00 sec)

第七小節:Slow_queries

如果你想查詢有多少條慢查詢記錄,可以使用 Slow_queries 系統變量。

mysql> show global status like '%Slow_queries%';
 +---------------+-------+
 | Variable_name | Value |
 +---------------+-------+
 | Slow_queries  | 2104  |
 +---------------+-------+
 1 row in set (0.00 sec)

04


mysqldumpslow 工具

在生產環境中,如果要手工分析日誌,查找、分析SQL,顯然是個體力活。

MySQL 提供了日誌分析工具 mysqldumpslow

查看 mysqldumpslow 的幫助信息:

[root@DB-Server ~]# 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(返回前面n條數據)
   -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

例如:

    (1)得到返回記錄集最多的10個SQL

mysqldumpslow -s r -t 10 /database/mysql/mysql06_slow.log

     (2)得到訪問次數最多的10個SQL

mysqldumpslow -s c -t 10 /database/mysql/mysql06_slow.log

     (3)得到按照時間排序的前10條裏面含有左連接的查詢語句

mysqldumpslow -s t -t 10 -g “left join” /database/mysql/mysql06_slow.log

另外建議在使用這些命令時結合 | 和more 使用 ,否則有可能出現刷屏的情況。

mysqldumpslow -s r -t 20 /mysqldata/mysql/mysql06-slow.log | more

————————end————————


歡迎大家加入WeChat 技術交流羣wechat:xzzs730

技術羣交流 長按 ↑ 上方二維碼 掃碼加羣 

鏈接地址技術羣分享-存檔記錄

https://github.com/gtcarry888/WeChat-Sharing-records

如有其他問題,可留言至 [email protected] 郵箱。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章