Mysql开启慢SQL并分析原因
第⼀步.开启mysql慢查询
⽅式⼀:修改配置⽂件
Windows:Windows 的配置⽂件为 my.ini,⼀般在 MySQL 的安装⽬录下或者 c:\Windows 下。
Linux:Linux 的配置⽂件为 myf ,⼀般在 /etc 下
在 my.ini 增加⼏⾏:
[mysqlld]
long_query_time=2
#5.0、5.1等版本配置如下选项
log-slow-queries="mysql_slow_query.log"
#5.5及以上版本配置如下选项
slow-query-log=On
slow_query_log_file="mysql_slow_query.log"
log-query-not-using-indexes
第⼀句使⽤来定义查过多少秒的查询算是慢查询,我这⾥定义的是2秒
第⼆句使⽤来定义慢查询⽇志的路径(因为是windows,所以不牵涉权限问题)
第三句就是记录下没有使⽤索引的query
第⼆步:查看关于慢查询的状态
⽅式⼆:通过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会将⽇志分别记录到表a_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慢查询的状态
执⾏结果会把是否开启慢查询、慢查询的秒数、慢查询⽇志等信息打印在屏幕上。
/*查看慢查询时间 */
show variables like "long_query_time";默认10s
/*查看慢查询配置情况 */
show status like "%slow_queries%";
/*查看慢查询⽇志路径 */
show variables like "%slow%";
第三步:执⾏⼀次慢查询操作
其实想要执⾏⼀次有实际意义的慢查询⽐较困难,因为在⾃⼰测试的时候,就算查询有20万条数据的海量表,也只需要0.⼏秒。我们可以通过如下语句代替:
SELECT SLEEP(10);
第四步:查看慢查询的数量
通过如下sql语句,来查看⼀共执⾏过⼏次慢查询:
show global status like '%slow%';
mysql⽇志的配置:
注意:这些⽇⽂件在mysql重启的时候才会⽣成
#记录所有sql语句
sql语句优化方式log=E:/mysqllog/mysql.log
#记录数据库启动关闭信息,以及运⾏过程中产⽣的错误信息
log-error=E:/mysqllog/myerror.log
# 记录除select语句之外的所有sql语句到⽇志中,可以⽤来恢复数据⽂件
log-bin=E:/mysqllog/bin
#记录查询慢的sql语句
log-slow-queries=E:/mysqllog/slow.log
#慢查询时间
long_query_time=2
第四步:分析慢查询⽇志
⽅式⼀:通过⼯具分析
以下是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命令查看慢查询语句,如下图:
问题很明显,解决⽅式也很明显,建索引了。
mysql> create index text_index on wei(text);
Query OK, 4194304 rows affected (1 min 58.07 sec)
Records: 4194304 Duplicates: 0 Warnings: 0
然后在执⾏查询操作,⽤时明显少了很多。
mysql> select * from wei where text='orange';
+---------+--------+
| id  | text  |
+---------+--------+
| 4103519 | orange |
+---------+--------+
1 row in set (0.33 sec)
Slow Query⽇志,虽然帮助你记录了那些执⾏过了的SQL语句。但它不是万能的,意义可能没有你想象的那么⼤。它只告诉了你哪些语句慢,但是为什么慢?具体原因,还是需要你⾃⼰去分析,不断的调试。也许,你只需要换⼀条更有效的sql语句,也许你只需简单地增加⼀个索引,但也有可能你需要调
整你应⽤程序的设计⽅案。⽐如,上⾯那条语句是很明显,它检查了600多万⾏数据。不幸的是,并不是每条语句都这么明显。也许还有别的原因,⽐如:
*锁表了,导致查询处于等态状态。lock_time显⽰了查询等待锁被翻译的时间
*数据或索引没有被缓存。常见于第⼀次启动服务器或者服务器没有调优
*备份数据库,I/O变慢
*也许同时运⾏了其它的查询,减少了当前查询
所以,不要过于紧张⽇志⽂件某条记录,⽽应该理性地审记,出真正的原因。如果经常出现的slow query需要特别注意。如果个别出现,则做⼀些常规检查即可。我们建议,统计并且形成基准报告,进⾏⽐较排除,⽐胡乱瞎撞有⽤。希望⼤家不要在这部分过于浪费时间与精⼒。
总结
以上就是这篇⽂章的全部内容了,希望本⽂的内容对⼤家的学习或者⼯作具有⼀定的参考学习价值,谢谢⼤家对的⽀持。如果你想了解更多相关内容请查看下⾯相关链接

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。