MySQL慢查询

慢查询(slow log)可以帮助我们定位到特定的SQL语句进行SQL语句层面的优化,例如,慢查询日志会记录那些执行时间超过给定值得SQL语句,从而定位到问题的所在。

开启慢查询

查看MySQL数据库实例关于慢查询的参数

  1. mysql> show variables like '%slow%'
  2. +---------------------------+-----------------------------------+  
  3. | Variable_name             | Value                             | 
  4. +---------------------------+-----------------------------------+  
  5. | log_slow_admin_statements | OFF                               | 
  6. | log_slow_slave_statements | OFF                               | 
  7. | slow_launch_time          | 2                                 | 
  8. | slow_query_log            | OFF                               | 
  9. | slow_query_log_file       | /var/lib/mysql/localhost-slow.log | 
  10. +---------------------------+-----------------------------------+  
  11. rows in set (0.00 sec) 
  12.  
  13. mysql> show variables like '%long_query_time%'
  14. +-----------------+-----------+  
  15. | Variable_name   | Value     | 
  16. +-----------------+-----------+  
  17. | long_query_time | 10.000000 | 
  18. +-----------------+-----------+  
  19. 1 row in set (0.02 sec) 
mysql> show variables like '%slow%';
+---------------------------+-----------------------------------+
| Variable_name             | Value                             |
+---------------------------+-----------------------------------+
| log_slow_admin_statements | OFF                               |
| log_slow_slave_statements | OFF                               |
| slow_launch_time          | 2                                 |
| slow_query_log            | OFF                               |
| slow_query_log_file       | /var/lib/mysql/localhost-slow.log |
+---------------------------+-----------------------------------+
5 rows in set (0.00 sec)

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


其中, 

slow_query_log便是开启慢查询的参数

slow_query_log_file是慢查询日志文件的路径

log_query_time是查询时间的最大值,超过这个时间就会被慢查询日志记录。

下面是开始慢查询,然后将查询时间最大值设为2秒,执行sleep3秒,查看慢查询日志的例子

  1. mysql> set global slow_query_log=ON
  2. Query OK, 0 rows affected (0.03 sec) 
  3.  
  4. mysql> set long_query_time=2; 
  5. Query OK, 0 rows affected (0.00 sec) 
  6.  
  7. mysql> show variables like '%long_query_time%'
  8. +-----------------+----------+  
  9. | Variable_name   | Value    | 
  10. +-----------------+----------+  
  11. | long_query_time | 2.000000 | 
  12. +-----------------+----------+  
  13. 1 row in set (0.00 sec) 
  14.  
  15. mysql> select sleep(3); 
  16. +----------+  
  17. | sleep(3) | 
  18. +----------+  
  19. |        0 | 
  20. +----------+  
  21. 1 row in set (3.00 sec) 
  22.  
  23. mysql> system cat /var/lib/mysql/localhost-slow.log 
  24. /usr/sbin/mysqld, Version: 5.6.22-log (MySQL Community Server (GPL)). started with
  25. Tcp port: 3306  Unix socket: /var/lib/mysql/mysql.sock 
  26. Time                 Id Command    Argument 
  27. Time: 150102 16:56:54 
  28. User@Host: root[root] @ localhost []  Id:     1 
  29. # Query_time: 3.001084  Lock_time: 0.000000 Rows_sent: 1  Rows_examined: 0 
  30. use test2; 
  31. SET timestamp=1420189014; 
  32. select sleep(3); 
mysql> set global slow_query_log=ON;
Query OK, 0 rows affected (0.03 sec)

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

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

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

mysql> system cat /var/lib/mysql/localhost-slow.log
/usr/sbin/mysqld, Version: 5.6.22-log (MySQL Community Server (GPL)). started with:
Tcp port: 3306  Unix socket: /var/lib/mysql/mysql.sock
Time                 Id Command    Argument
# Time: 150102 16:56:54
# User@Host: root[root] @ localhost []  Id:     1
# Query_time: 3.001084  Lock_time: 0.000000 Rows_sent: 1  Rows_examined: 0
use test2;
SET timestamp=1420189014;
select sleep(3);


慢查询还有一个参数log_queries_not_using_indexes,用来表示每分钟允许记录到慢查询日志的未使用索引的SQL语句的次数,默认为0,表示没有限制,但是生产环境中,这类语句会大量占据慢查询日志的大小,给DBA的分析带来困扰。 

除了使用日志文件查看慢查询日志,还可以使用表的形式查看。在数据库名为mysql的模式下,有一张叫做slow_log的表,可以记录慢查询的输出,只需改变日志的输出模式log_output,参数log_output是全局的动态的,可以在运行时动态的改变。

  1. mysql> show variables like '%log_output%'
  2. +---------------+-------+  
  3. | Variable_name | Value | 
  4. +---------------+-------+  
  5. | log_output    | FILE  | 
  6. +---------------+-------+  
  7. 1 row in set (0.00 sec) 
  8.  
  9. mysql> set global log_output='table'
  10. Query OK, 0 rows affected (0.00 sec) 
  11.  
  12. mysql> select sleep(3); 
  13. +----------+  
  14. | sleep(3) | 
  15. +----------+  
  16. |        0 | 
  17. +----------+  
  18. 1 row in set (3.00 sec) 
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> select sleep(3);
+----------+
| sleep(3) |
+----------+
|        0 |
+----------+
1 row in set (3.00 sec)


指的注意的是slow_log这张表的引擎室CSV,对于查询的效率可能不是很高,但是作为日志的追加插入效率很高。

  1. mysql> show create table slow_log\G 
  2. *************************** 1. row *************************** 
  3.        Table: slow_log 
  4. Create TableCREATE TABLE `slow_log` ( 
  5.   `start_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
  6.   `user_host` mediumtext NOT NULL
  7.   `query_time` time NOT NULL
  8.   `lock_time` time NOT NULL
  9.   `rows_sent` int(11) NOT NULL
  10.   `rows_examined` int(11) NOT NULL
  11.   `db` varchar(512) NOT NULL
  12.   `last_insert_id` int(11) NOT NULL
  13.   `insert_id` int(11) NOT NULL
  14.   `server_id` int(10) unsigned NOT NULL
  15.   `sql_text` mediumtext NOT NULL
  16.   `thread_id` bigint(21) unsigned NOT NULL 
  17. ) ENGINE=CSV DEFAULT CHARSET=utf8 COMMENT='Slow log' 
mysql> show create table slow_log\G
*************************** 1. row ***************************
       Table: slow_log
Create Table: CREATE TABLE `slow_log` (
  `start_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `user_host` mediumtext NOT NULL,
  `query_time` time NOT NULL,
  `lock_time` time NOT NULL,
  `rows_sent` int(11) NOT NULL,
  `rows_examined` int(11) NOT NULL,
  `db` varchar(512) NOT NULL,
  `last_insert_id` int(11) NOT NULL,
  `insert_id` int(11) NOT NULL,
  `server_id` int(10) unsigned NOT NULL,
  `sql_text` mediumtext NOT NULL,
  `thread_id` bigint(21) unsigned NOT NULL
) ENGINE=CSV DEFAULT CHARSET=utf8 COMMENT='Slow log'


关于慢查询的另外一个有用的参数是long_query_io表示将超过指定逻辑IO次数(逻辑IO包含物理IO,表示物理IO和缓冲池读取次数之和)的SQL语句记录到慢查询日志中去。

--------------------------------------分割线 --------------------------------------

--------------------------------------分割线 --------------------------------------

相关推荐