mysql:慢查询日志(slow_log)

本文介绍如何利用MySQL慢查询日志(slow_log)定位并优化执行效率低下的SQL语句,包括慢查询日志的开启、设置及使用方法,以及如何将慢查询日志输出至表并优化查询效率。

一、慢查询日志(slow_log)

慢查询日志(slow log)可帮助DBA定位可能存在问题的SQL语句,从而进行SQL语句层面的优化。例如,可以在MySQL启动时设一个阈值,将运行时间超过该值的所有SQL语句都记录到慢查询日志文件中。DBA每天或每过一段时间对其进行检查,确认是否有SQL语句需要进行优化。

二、慢查询日志设置

1. 慢查询日志开启

//开启慢查询日志
mysql> set global slow_query_log=ON;
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like 'slow_query%';
+---------------------+--------------------------------+
| Variable_name       | Value                          |
+---------------------+--------------------------------+
| slow_query_log      | ON                             |
| slow_query_log_file | /var/lib/mysql/ubuntu-slow.log |
+---------------------+--------------------------------+

2. 慢查询日志相关设置

(1) 设置sql语句超时时间

两点需要注意。首先,设置long_query_time这个阈值后,MySQL数据库会记录运行时间超过该值的所有SQL语句,但运行时间正好等于long_query_time的情况并不会被记录下。其次,从MySQL 5.1开始,long_query_time开始以微秒记录SQL语句运行的时间,之前仅用秒为单位记录。

//设置sql语句超时时间
mysql> show variables like 'long_query_time';
+-----------------+-----------+
| Variable_name   | Value     |
+-----------------+-----------+
| long_query_time | 10.000000 |
+-----------------+-----------+

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

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

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

mysql> select @@global.long_query_time;
+--------------------------+
| @@global.long_query_time |
+--------------------------+
|                 1.000000 |
+--------------------------+
1 row in set (0.00 sec)

mysql> select @@session.long_query_time;
+---------------------------+
| @@session.long_query_time |
+---------------------------+
|                  1.000000 |
+--------------------------
(2) 开启未使用索引查询的sql语句
//开启未使用索引查询的sql语句
mysql> set global log_queries_not_using_indexes=ON;
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    |
+-------------------------------+-------+

//每分钟允许记录到slow log的且未使用索引的SQL语句次数:0 无限制
mysql> show variables like 'log_throttle_queries_not_using_indexes';
+----------------------------------------+-------+
| Variable_name                          | Value |
+----------------------------------------+-------+
| log_throttle_queries_not_using_indexes | 0     |
+----------------------------------------+-------+

三、使用慢查询日志

1. 创建一个测试表

//选择测试库
mysql> show databases;
mysql> use learn;

//创建表
 create table t ( 
 		id INT AUTO_INCREMENT , 
 		a INT,
 	 	PRIMARY KEY (id)
 )ENGINE=InnoDB DEFAULT CHARSET=utf8;

//插入测试数据
INSERT INTO t (id,a) VALUES (1,1);
INSERT INTO t (id,a) VALUES (2,2);

//查看数据
mysql> select * from t;
+----+------+
| id | a    |
+----+------+
|  1 |    1 |
|  2 |    2 |
+----+------+

2. 相关操作

mysql> select * from t ;
mysql> select * from t where b=2;

//不按索引查询的sql语句
root@ubuntu:/var/lib/mysql# mysqldumpslow ubuntu-slow.log
Reading mysql slow query log from ubuntu-slow.log
Count: 1  Time=0.00s (0s)  Lock=0.00s (0s)  Rows=2.0 (2), root[root]@localhost
  select * from t

Count: 1  Time=0.00s (0s)  Lock=0.00s (0s)  Rows=1.0 (1), root[root]@localhost
  select * from t where a=N

//执行时间最长的10条SQL语句
root@ubuntu:/var/lib/mysql# mysqldumpslow -s al -n 10 ubuntu-slow.log
......

2. 慢查询日志表:slow_log

慢查询的日志记录可以设置写入 mysql.slow_log 表中

(1) 查看mysql.slow_log 表信息
//mysql版本
mysql> select version();
+-------------------------+
| version()               |
+-------------------------+
| 5.7.30-0ubuntu0.18.04.1 |
+-------------------------+
1 row in set (0.00 sec)


//mysql.slow_log 表信息
mysql> SHOW CREATE TABLE mysql.slow_log;
+----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table    | Create Table                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
+----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| slow_log | CREATE TABLE `slow_log` (
  `start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
  `user_host` mediumtext NOT NULL,
  `query_time` time(6) NOT NULL,
  `lock_time` time(6) 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` mediumblob NOT NULL,
  `thread_id` bigint(21) unsigned NOT NULL
) ENGINE=CSV DEFAULT CHARSET=utf8 COMMENT='Slow log' |
+----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
(2) 将慢查询输出格式由文件转化为表
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(10);
+-----------+
| sleep(10) |
+-----------+
|         0 |
+-----------+
1 row in set (10.00 sec)

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 |
+----------------------------+---------------------------+-----------------+-----------------+-----------+---------------+-------+----------------+-----------+-----------+------------------------------+-----------+
| 2020-07-17 16:01:31.610090 | root[root] @ localhost [] | 00:00:10.001169 | 00:00:00.000000 |         1 |             0 | learn |              0 |         0 |         0 | select sleep(10)             |         2 |
+----------------------------+---------------------------+-----------------+-----------------+-----------+---------------+-------+----------------+-----------+-----------+------------------------------+-----------+
(3) 修改mysql.slow_log 表存储引擎,提高在大数据下查询效率
//slow_log表使用的是CSV引擎,对大数据量下的查询效率可能不高。用户可以把slow_log表的引擎转换到MyISAM,并在start_time列上添加索引以进一步提高查询的效率
//不能忽视的是,将slow_log表的存储引擎更改为MyISAM后,还是会对数据库造成额外的开销。不过好在很多关于慢查询的参数都是动态的,用户可以方便地在线进行设置或修改。
mysql> SET GLOBAL slow_query_log=off;
Query OK, 0 rows affected (0.00 sec)

mysql> ALTER TABLE mysql.slow_log ENGINE=MyISAM;
Query OK, 4 rows affected (0.01 sec)
Records: 4  Duplicates: 0  Warnings: 0

mysql> SHOW CREATE TABLE mysql.slow_log;
+----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table    | Create Table                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
+----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| slow_log | CREATE TABLE `slow_log` (
  `start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
  `user_host` mediumtext NOT NULL,
  `query_time` time(6) NOT NULL,
  `lock_time` time(6) 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` mediumblob NOT NULL,
  `thread_id` bigint(21) unsigned NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Slow log' |
+----------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
在计算机科学和数学中,`log(n+1)` 通常用于描述某种对数增长的行为。它与算法复杂度分析、数据结构的效率评估、信息论以及统计学等多个领域密切相关。 ### 对数函数的基本意义 `log(n+1)` 是对数函数的一种形式,其中底数可以是任意正数(通常为 `e` 或 `10`)。在计算机科学中,它常用于表示时间复杂度或空间复杂度的增长速率。例如,在分析某些递归算法或数据结构操作(如二叉搜索树的查找、插入和删除)时,`log(n+1)` 可以表示操作的平均时间复杂度。[^1] ### 在算法分析中的应用 `log(n+1)` 常用于描述某些算法的渐进行为。例如,在分治算法中,如归并排序或快速排序,`log(n+1)` 可能出现在递归深度或子问题划分的分析中。对于某些递归关系,例如 `T(n) = T(n/2) + O(1)`,其解通常为 `O(log n)`,而 `log(n+1)` 可视为一种变体,尤其在边界条件处理时更准确地反映复杂度的增长趋势。[^1] ### 在信息论中的意义 在信息论中,`log(n+1)` 可用于描述熵的计算或编码长度的估计。例如,在香农熵的定义中,`log(n+1)` 可用于衡量一个离散随机变量的信息量。当某个事件的概率分布接近均匀分布时,`log(n+1)` 可提供一种近似的方法来估计所需的编码长度。 ### 在数据结构中的应用 在数据结构中,`log(n+1)` 通常用于描述树结构的高度,例如平衡二叉搜索树(如 AVL 树或红黑树)的高度通常为 `O(log n)`,而 `log(n+1)` 可作为更精确的上界估计。这种高度限制确保了树的操作(如查找、插入和删除)能够在对数时间内完成。 ### 在统计学中的意义 在统计学中,`log(n+1)` 可用于处理偏态分布的数据,特别是在数据预处理阶段。通过对数据进行对数变换,`log(n+1)` 可以减少数据的偏态,使其更接近正态分布,从而提高统计分析的有效性。[^1] ### 示例代码 以下是一个简单的 Python 示例,展示如何计算 `log(n+1)`: ```python import math def log_n_plus_1(n, base=math.e): return math.log(n + 1, base) # 示例 n = 10 print(f"log({n}+1) base e: {log_n_plus_1(n)}") print(f"log({n}+1) base 10: {log_n_plus_1(n, 10)}") ``` ### 相关问题 1. 为什么在算法分析中常用对数函数来描述时间复杂度? 2. `log(n+1)` 和 `log(n)` 在数学上的差异对算法分析有何影响? 3. 在哪些数据结构中会频繁使用 `log(n+1)` 来描述其性能? 4. `log(n+1)` 在信息论中如何用于衡量信息量? 5. 如何利用 `log(n+1)` 进行数据预处理以减少偏态?
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值