MySql日志(四)慢查询日志

查询超出变量 long_query_time 指定时间值的为慢查询。但是查询获取锁(包括锁等待)的时间不计入查询时间内。
mysql记录慢查询日志是在查询执行完毕且已经完全释放锁之后才记录的,因此慢查询日志记录的顺序和执行的SQL查询语句顺序可能会不一致(例如语句1先执行,查询速度慢,语句2后执行,但查询速度快,则语句2先记录)。
注意,MySQL 5.1之后就支持微秒级的慢查询超时时长,对于DBA来说,一个查询运行0.5秒和运行0.05秒是非常不同的,前者可能索引使用错误或者走了表扫描,后者可能索引使用正确。
另外,指定的慢查询超时时长表示的是超出这个时间的才算是慢查询,等于这个时间的不会记录。
和慢查询有关的变量:

long_query_time=10 # 指定慢查询超时时长(默认10),超出此时长的属于慢查询
log_output={
    
    TABLE|FILE|NONE} # 定义一般查询日志和慢查询日志的输出格式,默认为file
log_slow_queries={
    
    yes|no}    # 是否启用慢查询日志,默认不启用
slow_query_log={
    
    1|ON|0|OFF}  # 也是是否启用慢查询日志,此变量和log_slow_queries修改一个另一个同时变化
slow_query_log_file=/mydata/data/hostname-slow.log  #默认路径为库文件目录下主机名加上-slow.log
log_queries_not_using_indexes=OFF # 查询没有使用索引的时候是否也记入慢查询日志
一、启动和设置慢查询日志

现在启用慢查询日志。

mysql> set @@global.slow_query_log=on;

log_output={TABLE|FILE|NONE} # 定义一般查询日志和慢查询日志的输出格式,不指定时默认为file

二、查看慢查询日志

因为默认超时时长为10秒,所以进行一个10秒的查询。

mysql> select sleep(10);

查看慢查询日志文件。这里看到虽然sleep了10秒,但是最后查询时间超出了847微秒,因此这里也记录了该查询。

[root@VM_2_223_centos mysql]# tail -f  /var/lib/mysql/VM_2_223_centos-slow.log
Time                 Id Command    Argument
# Time: 2019-10-16T06:12:36.966416Z
# User@Host: root[root] @ localhost []  Id:    80
# Query_time: 20.000238  Lock_time: 0.000000 Rows_sent: 1  Rows_examined: 0
use db01;
SET timestamp=1571206356;
select sleep(20);
/usr/sbin/mysqld, Version: 5.7.28-log (MySQL Community Server (GPL)). started with:
Tcp port: 3306  Unix socket: /var/lib/mysql/mysql.sock
Time                 Id Command    Argument
# Time: 2020-12-01T08:54:59.153235Z
# User@Host: skip-grants user[root] @  [218.106.126.130]  Id:    23
# Query_time: 10.000395  Lock_time: 0.000000 Rows_sent: 1  Rows_examined: 0
use sys;
SET timestamp=1606812899;
select sleep(10);

随着时间的推移,慢查询日志文件中的记录可能会变得非常多,这对于分析查询来说是非常困难的。好在提供了一个专门归类慢查询日志的工具mysqldumpslow。

[root@xuexi data]# mysqldumpslow --help
  -d           debug 
  -v           verbose:显示详细信息
  -t NUM       just show the top n queries:仅显示前n条查询
  -a           don't abstract all numbers to N and strings to 'S':归类时不要使用N替换数字,S替换字符串
  -g PATTERN   grep: only consider stmts that include this string:通过grep来筛选select语句。

该工具归类的时候,默认会将同文本但变量值不同的查询语句视为同一类,并使用N代替其中的数值变量,使用S代替其中的字符串变量。可以使用-a来禁用这种替换。如:

Reading mysql slow query log from VM_2_223_centos-slow.log
Count: 1  Time=20.00s (20s)  Lock=0.00s (0s)  Rows=1.0 (1), root[root]@localhost
  select sleep(20)

Count: 1  Time=0.00s (0s)  Lock=0.00s (0s)  Rows=0.0 (0), 0users@0hosts
  # User@Host: skip-grants user[root] @  [218.106.126.130]  Id:    23
  # Query_time: 13.000312  Lock_time: 0.000000 Rows_sent: 1  Rows_examined: 0
  SET timestamp=1606813140;
  select sleep(13)

Count: 1  Time=0.00s (0s)  Lock=0.00s (0s)  Rows=0.0 (0), 0users@0hosts
  # User@Host: skip-grants user[root] @  [218.106.126.130]  Id:    23
  # Query_time: 10.000330  Lock_time: 0.000000 Rows_sent: 1  Rows_examined: 0
  SET timestamp=1606813127;
  select sleep(10)

Count: 1  Time=0.00s (0s)  Lock=0.00s (0s)  Rows=0.0 (0), 0users@0hosts
  # User@Host: skip-grants user[root] @  [218.106.126.130]  Id:    23
  # Query_time: 10.000395  Lock_time: 0.000000 Rows_sent: 1  Rows_examined: 0
  use sys;
  SET timestamp=1606812899;
  select sleep(10)

慢查询在SQL语句调优的时候非常有用,应该将它启用起来,且应该让慢查询阈值尽量小,例如1秒甚至低于1秒。就像一天执行上千次的1秒语句,和一天执行几次的20秒语句,显然更值得去优化这个1秒的语句。

猜你喜欢

转载自blog.csdn.net/jinhf10/article/details/110224614