首页 > 数据库 >mysql 优化之开启慢查询并分析原因

mysql 优化之开启慢查询并分析原因

时间:2023-11-09 10:33:51浏览次数:32  
标签:slow log 开启 查询 mysql query 日志


   第一步.开启mysql慢查询


方式一:修改配置文件

my.ini 增加几行:


slow_query_log = on #开启慢查询日志
slow_query_log_file = filename #指定日志文件保存路径,不指定的话默认在数据库文件目录下,名为hostname-slow.log
long_query_time = 2 #指定达到多少秒才算慢查询
long-queries-not-using-indexes #记录没有使用索引的查询语句
min_examined_row_limit = 1000 #记录查找了多达1000次而引起的慢查询
log-slow-admin-statements #记录ALTER TABLE等语句引发的慢查询
log-slow-slave-statements #记录从服务器产生的慢查询


   重启MySQL服务使配置生效

service mysqld restart

方式二:通过MySQL数据库开启慢查询



上文的配置需要重启mysql server进程mysqld才会生效。但是很多时候,尤其是产品运营环境,不希望每次修改都需要重新启动mysql服务器,也希望能在某些特定时间记 录。MySQL5.1给我们提供了更为灵活的运行时控制,使得你不必重新启动mysql服务器,也能选择性地记录或者不记录某些slow queries。

MySQL5.1中,提供了全局变量slow_query_log、slow_query_log_file可以灵活地控制enable/disable慢查询。同时可以通过long_query_time设置时间
#//启用slow query记录
#注意:设置了slow_query_log全局变量, log_slow_queries也会隐性地跟着改变

mysql>set global slow_query_log=ON

不幸运的是,在MySQL5.0并没有提供类似的全局变量来灵活控制,但是我们可以通过将long_query_time设置得足够大来避免记录某些查询语句。比如

mysql>set global long_query_time = 3600;
mysql>set global log_querise_not_using_indexes = ON;

MySQL5.0, 不关服务的情况下,希望不记录日志的办法是将日志文件成为/dev/null的符号链接(symbolic link)。注意:你只需要在改变后运行FLUSH LOGS以确定MYSQL释放当前的日志文件描述符,重新把日志记录到/dev/null

和MySQL5.0不同,MySQL5.1可以在运行时改变日记行为,将日志记录到数据库表中。只要将mysql全局变量log_output设置为 TABLE即可。MySQL会将日志分别记录到表mysql.gengera_log和mysql.slow_log二张表中。但是,我们推荐将日志记录 在日记文件中。
mysql> show variables like ‘log_output’\G
Variable_name: log_output
Value: FILE
mysql>set global log_output=’table’;
缺陷与审记

虽然记录了slow query能够帮助你优化产品。但是MySQL目前版本,还有几大蹩足的地方。
1.MySQL5.0版本, long_query_time时间粒度不够细,最小值为1秒。对于高并发性能的网页脚本而言,1秒出现的意义不大。即出现1秒的查询比较少。直到mysql5.1.21才提供更细粒度的long_query_time设定.
2.不能将服务器执行的所有查询记录到慢速日志中。虽然MySQL普通日志记录了所有查询,但是它们是解析查询之前就记录下来了。这意味着普通日志没办法包含诸如执行时间,锁表时间,检查行数等信息。
3.如果开启了log_queries_not_using_indexes选项,slow query日志会充满过多的垃圾日志记录,这些快且高效的全表扫描查询(表小)会冲掉真正有用的slow queries记录。比如select * from category这样的查询也会被记录下来。

通过microslow-patch补丁可使用更细的时间粒度,和记录所有执行过的sql语句。不过,使用这个补订不得不自己编译MySQL,出于稳定性考滤,我们推荐在开发测试环境,可以打上这个补丁,享受这个补丁带来的便利。在运营环境尽量不要这么做…

   第二步.验证慢查询是否开启


执行如下SQL语句来查看mysql慢查询的状态

执行结果会把是否开启慢查询、慢查询的秒数、慢查询日志等信息打印在屏幕上。

1. /*查看慢查询时间 */  
2. show variables like "long_query_time";默认10s  
3.   
4. /*查看慢查询配置情况 */  
5. show status like "%slow_queries%";  
6.   
7. /*查看慢查询日志路径 */  
8. like "%slow%";


第三步:执行一次慢查询操作


其实想要执行一次有实际意义的慢查询比较困难,因为在自己测试的时候,就算查询有20万条数据的海量表,也只需要0.几秒。我们可以通过如下语句代替:

SELECT SLEEP(10);


第四步:查看慢查询的数量


通过如下sql语句,来查看一共执行过几次慢查询:


show global status like '%slow%';


mysql日志的配置:



 


    1. 注意:这些日文件在mysql重启的时候才会生成  
    2. #记录所有sql语句  
    3. log=E:/mysqllog/mysql.log  
    4.   
    5. #记录数据库启动关闭信息,以及运行过程中产生的错误信息  
    6. log-error=E:/mysqllog/myerror.log  
    7.   
    8. # 记录除select语句之外的所有sql语句到日志中,可以用来恢复数据文件  
    9. log-bin=E:/mysqllog/bin  
    10.   
    11. #记录查询慢的sql语句  
    12. log-slow-queries=E:/mysqllog/slow.log    
    13.   
    14. #慢查询时间  
    15. long_query_time=2

       第四步:分析慢查询日志

    方式一:通过工具分析

    MySQL自带了mysqldumpslow工具用来分析slow query日志,除此之外,还有一些好用的开源工具。比如MyProfi(下载地址:http://sourceforge.NET/projects/myprofi/)、mysql-log-filter,当然还有mysqlsla

    以下是mysqldumpslow常用参数说明,详细的可应用mysqldumpslow -help查询。

        -s,是表示按照何种方式排序,c、t、l、r分别是按照记录次数、时间、查询时间、返回的记录数来排序(从大到小),ac、at、al、ar表示相应的倒叙。 
    -t,是top n的意思,即为返回前面多少条数据。
    -g,后边可以写一个正则匹配模式,大小写不敏感。


    接下来就是用mysql自带的慢查询工具mysqldumpslow分析了(mysql的bin目录下),我这里的日志文件名字是host-slow.log。

    列出记录次数最多的10个sql语句

    mysqldumpslow -s c -t 10 host-slow.log

    列出返回记录集最多的10个sql语句

    mysqldumpslow -s r -t 10 host-slow.log

    按照时间返回前10条里面含有左连接的sql语句

    mysqldumpslow -s t -t 10 -g "left join" host-slow.log

    使用mysqldumpslow命令可以非常明确的得到各种我们需要的查询语句,对MySQL查询语句的监控、分析、优化起到非常大的帮助。

    方式二:直接分析mysql慢查询日志

    日志部分内容如下:

    # 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'; 

    其实定位到了慢查询语句就已经完成了一大不了,执行explain或者desc命令查看慢查询语句,如下图:

     

    问题很明显,解决方式也很明显,建索引了。


      1. mysql> create index text_index on wei(text);    
      2. Query OK, 4194304 rows affected (1 min 58.07 sec)    
      3. Records: 4194304  Duplicates: 0  Warnings: 0


      然后在执行查询操作,用时明显少了很多。

      1. mysql> select * from wei where text='orange';  
      2. +---------+--------+  
      3. | id      | text   |  
      4. +---------+--------+  
      5. | 4103519 | orange |  
      6. +---------+--------+  
      7. 1 row in set (0.33 sec)


      Slow Query日志,虽然帮助你记录了那些执行过了的SQL语句。但它不是万能的,意义可能没有你想象的那么大。它只告诉了你哪些语句慢,但是为什么慢?具体 原因,还是需要你自己去分析,不断的调试。也许,你只需要换一条更有效的sql语句,也许你只需简单地增加一个索引,但也有可能你需要调整你应用程序的设 计方案。比如,上面那条语句是很明显,它检查了600多万行数据。不幸的是,并不是每条语句都这么明显。也许还有别的原因,比如:
      *锁表了,导致查询处于等态状态。lock_time显示了查询等待锁被翻译的时间
      *数据或索引没有被缓存。常见于第一次启动服务器或者服务器没有调优
      *备份数据库,I/O变慢
      *也许同时运行了其它的查询,减少了当前查询

      所以,不要过于紧张日志文件某条记录,而应该理性地审记,找出真正的原因。如果经常出现的slow query需要特别注意。如果个别出现,则做一些常规检查即可。我们建议,统计并且形成基准报告,进行比较排除,比胡乱瞎撞有用。希望大家不要在这部分过于浪费时间与精力。


      标签:slow,log,开启,查询,mysql,query,日志
      From: https://blog.51cto.com/u_809530/8273131

      相关文章

      • mysql常见问题及排查步骤
        问题一:数据库连接串测试报错:Couldnotcreateconnectiontodatabaseserver.504错误遇到数据库问题的通用排查步骤确定数据库没有挂确定远程可以连接(前两个可以通过在本地连接验证)以上都OK,大概率服务器ip被限制访问,如果不是人为限制,在可以访问的服务器连上对应数据库,执行......
      • mysql8.x通过备份文件及binlog日志恢复数据
        问题简述记一次mysql数据库被误删(是整个库被删了)后的还原前提条件数据库版本为mysql8.x以上具有库被删除前的完整备份数据库开启binlog还原步骤第一步:通过完整备份还原被删的库注意事项:还原后切勿让其他用户连接,操作数据库。待使用binlog日志恢复数据后再对库进行操作,否......
      • MySQL到底是 join 性能好,还是in一下更快呢?
        事情是这样的,去年入职的新公司,之后在代码review的时候被提出说,不要写join,join耗性能还是慢来着,当时也是真的没有多想,那就写in好了,最近发现in的数据量过大的时候会导致sql慢,甚至sql太长,直接报错了。这次来浅究一下,到底是in好还是join好,仅目前认知探寻,有不对之处欢迎指正以下实验仅......
      • 记录一次报错,程序启动,MySql自动关闭
        关于初级程序员,对于安装mysql,以及配置可能会报几次错有时候虽然进行第二次安装成功,但是第一次的残留文件还在,可能引起报错在这里记录一次我的报错程序启动导致Mysql自动断开,需要手动打开1、打开任务管理器,打开详细信息,发现界面有两个mysqld.exe如果你是使用单程序连接,或者你......
      • 爬虫-mysql-工具
        MySQL数据库一、MySQL数据库的介绍1、发展史1996年,MySQL1.02008年1月16号Sun公司收购MySQL。2009年4月20,Oracle收购Sun公司。MySQL是一种开放源代码的关系型数据库管理系统(RDBMS),使用最常用的数据库管理语言--结构化查询语言(SQL)进行数据库管理。MySQL是开放源代码的,因此任......
      • elasticsearch在Java中查询指定列的方法
         背景ES在查询时如果数量太多,而每行记录包含的字段很多,那就会导致超出ES的查询上线,默认是100MB,但是很多场景下我们只需要返回特定的字段即可,那么如何操作呢。主要代码@AutowiredprivateRestHighLevelClientclient;publicList<Map<String,Object>>search(Stringin......
      • Mysql的SQL优化
        1.插入数据环境准备,创建表tb_testcreatetabletb_test(idintnotnullcomment'主键'primarykey,namevarchar(20)nullcomment'姓名',gendercharnullcomment'性别默认1表示男')comment'测试';1.1.inser......
      • Python 数据库应用教程:安装 MySQL 及使用 MySQL Connector
        Python可以用于数据库应用程序。其中最流行的数据库之一是MySQL。MySQL数据库为了能够在本教程中尝试代码示例,您应该在计算机上安装MySQL。您可以在MySQL官方网站下载MySQL数据库。安装MySQL驱动程序Python需要一个MySQL驱动程序来访问MySQL数据库。在本教程中,我们将使用"......
      • Python 数据库应用教程:安装 MySQL 及使用 MySQL Connector
        Python可以用于数据库应用程序。其中最流行的数据库之一是MySQL。MySQL数据库为了能够在本教程中尝试代码示例,您应该在计算机上安装MySQL。您可以在MySQL官方网站下载MySQL数据库。安装MySQL驱动程序Python需要一个MySQL驱动程序来访问MySQL数据库。在本教程中,我们将使用......
      • openEuler22.03操作系统 Linux内核Kernel 5.10 应该选择哪个版本的mysql安装包下载?
        对于openEuler22.03操作系统和Linux内核Kernel5.10,你应该选择与该操作系统和内核版本兼容的MySQL安装包进行安装。在确定适合的MySQL版本时,你可以考虑以下几点:MySQL官方支持:查看MySQL官方网站中的文档或支持页面,确认其是否支持openEuler22.03操作系统和Kernel5.......