文章目录:
1.数据库服务器的优化步骤
当我们遇到数据库调优问题的时候,该如何思考呢?这里把思考的流程整理成下面这张图。
整个流程划分成了观察(Show status)和行动(Action)两个部分。字母 S 的部分代表观察(会使用相应的分析工具),字母 A 代表的部分是行动(对应分析可以采取的行动)。
2.查看系统性能参数
在MySQL中,可以使用SHOW STATUS 语句查询一些MySQL数据库服务器的性能参数、执行频率。
SHOW STATUS语句语法如下:
SHOW [GLOBAL|SESSION] STATUS LIKE '参数';
一些常用的性能参数如下:
• Connections:连接MySQL服务器的次数。
• Uptime:MySQL服务器的上线时间。
• Slow_queries:慢查询的次数。
• Innodb_rows_read:Select查询返回的行数
• Innodb_rows_inserted:执行INSERT操作插入的行数
• Innodb_rows_updated:执行UPDATE操作更新的行数
• Innodb_rows_deleted:执行DELETE操作删除的行数
• Com_select:查询操作的次数。
• Com_insert:插入操作的次数。对于批量插入的 INSERT 操作,只累加一次。
• Com_update:更新操作的次数。 • Com_delete:删除操作的次数。
3.定位执行慢的 SQL:慢查询日志
开启slow_query_log
然后我们再来查看下慢查询日志是否开启,以及慢查询日志文件的位置:
你能看到这时慢查询分析已经开启,同时文件保存在/var/lib/mysql/atguigu02-slow.log 文件中。
修改long_query_time阈值。接下来我们来看下慢查询的时间阈值设置,使用如下命令:
这里如果我们想把时间缩短,比如设置为 0.5 秒
查看慢查询数目
下面,我们做一个简单的案例演示:首先会有一些建表语句、存储过程、存储函数。(向表中添加了四百万条数据,时间会有点长。。。)
CREATE TABLE `student` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `stuno` INT NOT NULL , `name` VARCHAR(20) DEFAULT NULL, `age` INT(3) DEFAULT NULL, `classId` INT(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; DELIMITER // CREATE FUNCTION rand_string(n INT) RETURNS VARCHAR(255) #该函数会返回一个字符串 BEGIN DECLARE chars_str VARCHAR(100) DEFAULT 'abcdefghijklmnopqrstuvwxyzABCDEFJHIJKLMNOPQRSTUVWXYZ'; DECLARE return_str VARCHAR(255) DEFAULT ''; DECLARE i INT DEFAULT 0; WHILE i < n DO SET return_str =CONCAT(return_str,SUBSTRING(chars_str,FLOOR(1+RAND()*52),1)); SET i = i + 1; END WHILE; RETURN return_str; END // DELIMITER ; DELIMITER // CREATE FUNCTION rand_num (from_num INT ,to_num INT) RETURNS INT(11) BEGIN DECLARE i INT DEFAULT 0; SET i = FLOOR(from_num +RAND()*(to_num - from_num+1)) ; RETURN i; END // DELIMITER ; DELIMITER // CREATE PROCEDURE insert_stu1( START INT , max_num INT ) BEGIN DECLARE i INT DEFAULT 0; SET autocommit = 0; #设置手动提交事务 REPEAT #循环 SET i = i + 1; #赋值 INSERT INTO student (stuno, NAME ,age ,classId ) VALUES ((START+i),rand_string(6),rand_num(10,100),rand_num(10,1000)); UNTIL i = max_num END REPEAT; COMMIT; #提交事务 END // DELIMITER ; #调用刚刚写好的函数, 4000000条记录,从100001号开始 CALL insert_stu1(100001,4000000); SELECT COUNT(*) FROM student;
表和数据都准备就绪之后,下面我们来测试。
这两条sql的执行时间都超过了我们自定义的long_query_time阈值,所以我们就可以查看慢查询数目
慢查询日志分析工具:mysqldumpslow
在生产环境中,如果要手工分析日志,查找、分析SQL,显然是个体力活,MySQL提供了日志分析工具mysqldumpslow 。
查看mysqldumpslow的帮助信息
mysqldumpslow --help
mysqldumpslow 命令的具体参数如下:
-a: 不将数字抽象成N,字符串抽象成S
-s: 是表示按照何种方式排序:
c: 访问次数
l: 锁定时间
r: 返回记录
t: 查询时间
al:平均锁定时间
ar:平均返回记录数
at:平均查询时间(默认方式)
ac:平均查询次数
-t: 即为返回前面多少条的数据;
-g: 后边搭配一个正则匹配模式,大小写不敏感的;
对刚才的案例进行分析:(这里可以看到慢查询日志已经记录下了刚刚我们执行的两次超过0.5s的sql)
#得到返回记录集最多的10个SQL mysqldumpslow -s r -t 10 /var/lib/mysql/localhost-slow.log #得到访问次数最多的10个SQL mysqldumpslow -s c -t 10 /var/lib/mysql/localhost-slow.log #得到按照时间排序的前10条里面含有左连接的查询语句 mysqldumpslow -s t -t 10 -g "left join" /var/lib/mysql/localhost-slow.log #另外建议在使用这些命令时结合 | 和more 使用 ,否则有可能出现爆屏情况 mysqldumpslow -s r -t 10 /var/lib/mysql/localhost-slow.log | more
因为我们如何不调优了话,最好还是不要开启慢查询日志,因为开启之后也会影响一定的性能。
所以下面来说一下关闭慢查询日志。
方式一:永久性关闭,或者,把slow_query_log一项注释掉或删除。 操作之后记得重启mysql服务
[mysqld] slow_query_log=OFF [mysqld] #slow_query_log =OFF
方式二:临时性关闭。这里先对slow_query_log参数做一个修改。然后重启mysql服务,long_query_time这个参数就会重置为最初的10s。
删除慢查询日志
4.查看 SQL 执行成本:SHOW PROFILE
下面我们执行两条sql。
然后,我们再次通过show profiles命令查看。