mysql慢查詢日誌對於跟蹤有問題的查詢非常有用,可以分析出代碼實現中耗費資源的sql語句,對我們程序的優化有很高的參考。本篇主要將慢查詢日誌的開啓,日誌分析,這也是優化SQL程序的一般步驟中至關重要的一步。
1.mysql慢查詢日誌
打開mysql的慢查詢日誌很簡單,只需要在mysql的配置文件裏(windows系統是my.ini,linux系統是my.cnf)的[mysqld]下面加上
log-slow-queries=mysql_slow.log
long_query_time=3
log-slow-queries=mysql_slow.log long_query_time=3
其中log-slow-queries爲日誌的文件名,可以指定目錄,如log-slow-queries=D:\mysql_slow.log; long_query_time爲定義多長的查詢我們定義爲慢查詢,並記錄在log-slow-queries 指定的文件中,在這裏我們定義超過3秒的查詢進行記錄。
配置完成以後重啓Mysql服務器,執行show variables like '%slow%';查看慢查詢日誌是否開啓,如果slow_query_log和log_slow_queries顯示爲on,那說明服務器的慢查詢日誌已
經開啓了。如下顯示:
mysql> show variables like '%slow%';
+---------------------+----------------+
| Variable_name | Value |
+---------------------+----------------+
| log_slow_queries | ON |
| slow_launch_time | 2 |
| slow_query_log | ON |
| slow_query_log_file | mysql_slow.log |
+---------------------+----------------+
4 rows in set (0.00 sec)
mysql> show variables like '%slow%'; +---------------------+----------------+ | Variable_name | Value | +---------------------+----------------+ | log_slow_queries | ON | | slow_launch_time | 2 | | slow_query_log | ON | | slow_query_log_file | mysql_slow.log | +---------------------+----------------+ 4 rows in set (0.00 sec)
slow_launch_time跟慢查詢日誌沒有任何關係, 它代表的是thread create的一個閾值,如果要看 long_query_time,可以用
mysql> show variables like '%long%';
+-----------------+----------+
| Variable_name | Value |
+-----------------+----------+
| long_query_time | 3.000000 |
+-----------------+----------+
1 row in set (0.00 sec)
mysql> show variables like '%long%'; +-----------------+----------+ | Variable_name | Value | +-----------------+----------+ | long_query_time | 3.000000 | +-----------------+----------+ 1 row in set (0.00 sec)
2.mysql慢查詢日誌分析
建表如下圖,建表勿要給text加上索引,否則可能出現不了超過3秒的查詢,數據表填充了4194304條數據。
我們來執行一個超過3秒的查詢,如下:
mysql> select * from wei where text='orange';
+---------+--------+
| id | text |
+---------+--------+
| 4103519 | orange |
+---------+--------+
mysql> select * from wei where text='orange'; +---------+--------+ | id | text | +---------+--------+ | 4103519 | orange | +---------+--------+
1 row in set (3.79 sec)
再執行一個超過3秒的和一個沒有超過3秒的:
mysql> select * from wei where text='xishizhaohua';
Empty set (3.82 sec)
mysql> select * from wei where text='xishizhaohua'; Empty set (3.82 sec)
[mysql> select * from wei where id=4564;
+------+--------------------+
| id | text |
+------+--------------------+
| 4564 | yyyyyyyyyyyyyyyyyy |
+------+--------------------+
1 row in set (0.02 sec)
[mysql> select * from wei where id=4564; +------+--------------------+ | id | text | +------+--------------------+ | 4564 | yyyyyyyyyyyyyyyyyy | +------+--------------------+ 1 row in set (0.02 sec)
可以通過下面的命令查看現在這個session有多少個慢查詢:
現在我們可以查看mysql_slow.log(win7默認在C:\ProgramData\MySQL\MySQL Server 5.1\data下面),裏邊內容如下,內容比較明瞭,包括查詢花費的語句及時間,還包括查詢時的時間戳等信息,其中Rows_examined爲檢查的行數,對我們優化也很有幫助
# Time: 121017 17:38:54
# User@Host: root[root] @ localhost [127.0.0.1]
# Query_time: 3.794217 Lock_time: 0.000000 Rows_sent: 1 Rows_examined: 4194304
SET timestamp=1350466734;
select * from wei where text='orange';
# Time: 121017 17:46:22
# User@Host: root[root] @ localhost [127.0.0.1]
# Query_time: 3.819219 Lock_time: 0.000000 Rows_sent: 0 Rows_examined: 4194304
SET timestamp=1350467182;
select * from wei where text='xishizhaohua';
3.優化
其實定位到了慢查詢語句就已經完成了一大不了,執行explain或者desc命令查看慢查詢語句,如下圖:
問題很明顯,解決方式也很明顯,建索引了。
mysql> create index text_index on wei(text);
Query OK, 4194304 rows affected (1 min 58.07 sec)
Records: 4194304 Duplicates: 0 Warnings: 0
mysql> create index text_index on wei(text); Query OK, 4194304 rows affected (1 min 58.07 sec) Records: 4194304 Duplicates: 0 Warnings: 0
然後在執行查詢操作,用時明顯少了很多。
mysql> select * from wei where text='orange';
+---------+--------+
| id | text |
+---------+--------+
| 4103519 | orange |
+---------+--------+
1 row in set (0.33 sec)
mysql> select * from wei where text='orange'; +---------+--------+ | id | text | +---------+--------+ | 4103519 | orange | +---------+--------+ 1 row in set (0.33 sec)
mysql> select * from wei where text='xishizhaohua';
Empty set (0.01 sec)
mysql> select * from wei where text='xishizhaohua'; Empty set (0.01 sec)