• MySQL调优之慢查询日志应用


    【1】慢查询日志

    ① 什么是慢查询日志

    慢查询日志是用于记录SQL执行时间超过某个临界值的SQL日志文件,可用于快速定位慢查询,为我们的SQL优化做参考。

    具体指运行时间超过long_query_time值的SQL,则会被记录到慢查询日志中。long_query_time的默认值为10,意思是运行10秒以上的SQL语句,认为是超出了我们的最大忍耐时间值。

    它的主要作用是帮助我们发现那些执行时间特别长的SQL查询,并且有针对性地进行优化,从而提高系统的整体效率。当我们的数据库服务器发生阻塞、运行变慢的时候,检查一下慢查询日志,找到那些慢查询,对解决问题有帮助。

    默认情况下,MySQL数据库没有开启慢查询日志,需要我们手动来设置这个参数。如果不是调优需要的话,一般不建议启动该参数,因为开启慢查询日志会或多或少带来一定的性能影响。

    ② 开启慢查询日志

    查看是否开启

    show variables like '%slow_query_log%'
    
    # 本文这里结果如下
    slow_query_log	ON
    slow_query_log_file	DESKTOP-KIHKQLG-slow.log
    
    • 1
    • 2
    • 3
    • 4
    • 5

    slow_query_log_file指的是慢查询日志文件。如果slow_query_log 状态值为OFF,可以使用set GLOBAL slow_query_log = on来开启,如果想永久生效,那么在MySQL的配置文件中进行配置。

    [mysqld]
    slow_query_log=ON  # 开启慢查询日志
    slow_query_log_file=/var/data/mysql-slow.log  # 慢查询日志的文件信息
    #如果不指定日志文件,那么系统会默认一个hostnam-slow.log
    long_query_time=3 #设置慢查询的阈值为3秒,超过此设定值的SQL即被记录到慢查询日志
    log_output=FILE
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    查看时间阈值

    默认值是10秒,可以根据需求自行调整。

    show variables like 'long_query_time';
    
    # 临时设置为1 秒,重启失效
    set GLOBAL long_query_time= 1
    
    #针对当前会话级别设置
    set  long_query_time= 1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    查询当前慢查询SQL条数

    # 查询当前系统中有多少条慢查询记录
    show global status like '%Slow_queries%'
    
    • 1
    • 2

    ③ 慢查询日志格式

    需要注意的是,慢查询日志文件里面不止有Query哦,只要执行时间大于我们设置的阈值都会进入。

    如下所示是一个慢查询实例,其load了21W条数据。

    # Time: 2022-09-14T05:43:57.174825Z
    # User@Host: root[root] @ localhost [127.0.0.1]  Id:  2497
    # Query_time: 1.697595  Lock_time: 0.000226 Rows_sent: 210001  Rows_examined: 210001
    SET timestamp=1663134237;
    /* ApplicationName=DBeaver 7.3.0 - SQLEditor  */ select * from tb_sys_user tsu limit 210001;
    
    • 1
    • 2
    • 3
    • 4
    • 5

    ④ min_examined_row_limit

    除了上述变量外,控制慢查询日志的还有一个系统变量:min_examined_row_limit 。这个变量的意思是,查询扫描过得最少记录数。这个变量和查询执行时间,共同组成了判别一个查询是否是慢查询的条件。如果查询扫描过得记录数大于等于这个变量的值,并且查询执行时间超过 long_query_time 的值,那么这个查询就被记录到慢查询日志中,反之则不被记录到慢查询日志中。

    # 默认值 0
    show variables like 'min_examined_row_limit';
    
    • 1
    • 2

    这个值默认是0。 与 long_query_time=10 结合在一起,表示只要查询的执行时间超过10秒钟,哪怕一个记录也没有扫描过,都要被记录到慢查询日志中。


    ⑤ 关闭慢查询日志

    永久性关闭

    修改my.cnf或者my.ini文件,把 slow_query_log设置为OFF,然后重启MySQL服务。

    [mysqld]
    slow_query_log=OFF
    
    • 1
    • 2

    临时性关闭

    set global slow_query_log=off
    
    • 1

    ⑥ 删除慢查询日志

    可以通过查到慢查询日志文件位置,手动删除日志文件。

    show variables like 'slow_query_log_file'
    
    • 1

    使用命令 mysqladmin flush-logs 来重新生成慢查询日志文件,执行完毕会在数据目录下重新生成慢查询日志文件。

    mysqladmin -uroot -p flush-logs slow
    
    • 1

    通常慢查询日志都是使用mysqladmin flush-logs命令来删除重建的。使用时一定要注意,一旦执行了这个命令,慢查询日志都只存在新的日志文件中,如果需要旧的查询日志,就必须事先备份。

    ⑦ 慢查询日志场景应用

    慢查询的优化首先要搞明白慢的原因是什么, 是查询条件没有命中索引?是 load了不需要的数据列?还是数据量太大?所以优化也是针对这三个方向来的。

    首先分析语句,看看是否load了额外的数据,可能是查询了多余的行并且抛弃掉了,可能是加载了许多结果中并不需要的列,对语句进行分析以及重写。

    分析语句的执行计划,然后获得其使用索引的情况,之后修改语句或者修改索引,使得语句可以尽可能的命中索引。

    如果对语句的优化已经无法进行,可以考虑表中的数据量是否太大,如果是的话可以进行横向或者纵向的分表。


    【2】慢查询日志分析工具mysqldumpslow

    mysql提供了日志分析工具mysqldumpslow来帮助我们快速定位问题。

    # 查看mysqldumpslow 的帮助信息
    [root@VM-24-14-centos ~]# 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
      -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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    得到返回记录集最多的10个SQL

    mysqldumpslow -s r -t 10 /var/data/mysql-slow.log
    
    • 1

    得到访问次数最多的10个SQL

    mysqldumpslow -s c -t 10 /var/data/mysql-slow.log
    
    • 1

    得到按照时间排序的前10条SQL中包含左连接的语句

    mysqldumpslow -s t -t 10 -g "left join" /var/data/mysql-slow.log
    
    • 1

    【3】全局查询日志

    其同样可以帮助我们定位SQL问题,通常不建议在生产环境开启。可以在配置文件my.cnf下进行启用:

    # 开启
    general_log=1
    #记录日志文件的路径
    general_log_file=/var/data/mysql_general_log
    #输出格式
    log_output=FILE
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    或者临时开启:

    set global general_log=1;
    set global log_output='TABLE'
    
    • 1
    • 2

    此时SQL语句将会记录到MySQL库的mysql.general_log表中。

  • 相关阅读:
    痞子衡嵌入式:MCUXpresso IDE下将源码制作成Lib库方法及其与IAR,MDK差异
    【Fusion360】常用快捷键和技巧
    三年半经验,成功拿下字节阿里网易offer
    视频汇聚/安防监控/EasyCVR平台播放器EasyPlayer更新:新增【性能面板】
    创建对象在堆区如何分配内存
    UE4实现光束和体积雾
    【Qt】Qt中将字符串转换为数字类型的函数总结以及用法示例
    SpringBoot序幕——SpringBoot概述及其项目创建
    AI图书推荐:基于ChatGPT API和Python开发应用程序的详细指南
    Mybatis plus 一对多关联查询分页不准确的问题
  • 原文地址:https://blog.csdn.net/J080624/article/details/126850312