MySQL5.7.26的安装详见:https://blog.csdn.net/niuxitong/article/details/89915566
1、MySQL中的日志
MySQL日志文件系统的组成
a、错误日志:记录启动、运行或停止mysqld时出现的问题。
b、通用日志:记录建立的客户端连接和执行的语句。
c、更新日志:记录更改数据的语句。该日志在MySQL 5.1中已不再使用。
d、二进制日志:记录所有更改数据的语句。还用于复制。
e、慢查询日志:记录所有执行时间超过long_query_time秒的所有查询或不使用索引的查询。
f、Innodb日志:innodb redo log
缺省情况下,所有日志创建于mysqld数据目录中。同大多数关系型数据库一样,日志文件是MySQL数据库的重要组成部分。MySQL有几种不同的日志文件,通常包括错误日志文件,二进制日志,通用日志,慢查询日志,等等。这些日志可以帮助我们定位mysqld内部发生的事件,数据库性能故障,记录数据的变更历史,用户恢复数据库等等。今天我们要讲的是如何分析和查询mysql慢日志(主要影响程序调用和前端数据呈现)。
2、什么是慢查询
MySQL的慢查询日志是MySQL提供的一种日志记录,用来记录在MySQL中响应时间超过阈值的语句,具体指运行时间超过long_query_time值的SQL,则会被记录到慢查询日志中(日志可以写入文件或者数据库表,如果对性能要求高的话,建议写文件)。long_query_time的默认值为10(即10秒,通常设置为1秒),即运行10秒以上的语句是慢查询语句。
默认情况下,Mysql数据库并不启动慢查询日志(即slow_query_log参数值为OFF),需要我们手动来设置这个参数,如果不是调优需要,一般不建议启动该参数,因为开启慢查询日志会或多或少带来一定的性能影响。
3、慢查询相关参数
slow_query_log=1 # 是否开启慢查询日志,1表示开启,0表示关闭。
long_query_time=1 # 慢查询阈值秒,默认值为10秒,通常设置为1秒,当查询时间多于设定的阈值时,记录日志。
slow-query-log-file=/usr/local/mysql/data/localhost-slow.log #新版(5.6及以上版本)MySQL数据库慢查询日志存储路径。可以不设置该参数,系统则会默认给一个缺省的文件 服务器名-slow.log,并保存到datadir目录下
#log-slow-queries :旧版(5.6以下版本)MySQL数据库慢查询日志存储路径。可以不设置该参数,系统则会默认给一个缺省的文件 服务器名-slow.log,并保存到datadir目录下
#log_queries_not_using_indexes=0 # 1表示开启,0表示关闭。 如果值设置为ON,未使用索引的查询也被记录到慢查询日志中(性能优化时开启此项,平时不要开启)开启了这个参数,其实使用full index scan的sql也会被记录到慢查询日志
#log_output='FILE' # 日志存储方式,默认值是'FILE',文件效率高
其中 #log_output='TABLE'表示将日志存入数据库,这样日志信息就会被写入到mysql.slow_log表中。MySQL数据库支持同时两种日志存储方式,配置的时候以逗号隔开即可,如:log_output='FILE,TABLE'。日志记录到系统的专用日志表中,要比记录到文件耗费更多的系统资源,因此对于需要启用慢查询日志,又需要能够获得更高的系统性能,那么建议优先记录到文件。
1、查看慢查询日志的开启状态和慢查询日志储存的位置
mysql> show variables like '%query%';
mysql> show variables like '%slow_query_log%';
2、开启临时慢查询
#开启了慢查询日志只对当前数据库生效,MySQL重启后则会失效。如果要永久生效,就必须修改配置文件my.cnf(其它系统变量也是如此)
mysql> set global slow_query_log=1; #开启慢查询
mysql> set global slow_query_time=1; #设置阈值为1秒
mysql> set global slow_query_log_file='/usr/local/mysql/log/qinser-slow.log' #重新定义慢查询日志的存放目录
Query OK, 0 rows affected (0.01 sec)
mysql> show variables like '%slow_query_log%';
+---------------------+---------------------------------------+
| Variable_name | Value |
+---------------------+---------------------------------------+
| slow_query_log | ON | <----ON已经开启
| slow_query_log_file | /usr/local/mysql/data/qinser-slow.log |
+---------------------+---------------------------------------+
mysql> set global long_query_time=1; #设置阈值为1秒
Query OK, 0 rows affected (0.00 sec)
mysql>
mysql> show variables like 'long_query_time';
+-----------------+-----------+
| Variable_name | Value |
+-----------------+-----------+
| long_query_time | 10.000000 | <------上面已经修改过了,为什么这里还是10呢???
+-----------------+-----------+
#注意:使用命令 set global long_query_time=4修改后,需要重新连接或新开一个会话才能看到修改值。你用show variables like 'long_query_time'查看是当前会话的变量值,你也可以不用重新连接会话,而是用show global variables like 'long_query_time';
mysql> show global variables like 'long_query_time';
+-----------------+----------+
| Variable_name | Value |
+-----------------+----------+
| long_query_time | 1.000000 |
+-----------------+----------+
#-- 设置慢查询的存储方式-- 默认为FILE 。如果要修改,使用以下方法,其值可以为 'file'|'table'|'file,table'
mysql> set global log_output='file';
mysql> show variables like '%log_output%';
3、永久开启慢查询
把配置项写入/etc/my.cnf配置文件中
slow_query_log=1 # 是否开启慢查询,默认不开启,1开启 0不开启
slow_query_log_file=/usr/local/mysql/log/qinser-slow.log #自定义默认慢查询日志
long_query_time=1
然后重启mysql (必须使用 restart, 使用reload可能无效)这时已经在数据库文件存放目录生成了qinser-slow.log文件。
1、创建演示数据
# 建表语句:
CREATE TABLE `qs_news` (
`id` INT(10) NOT NULL AUTO_INCREMENT,
`title` VARCHAR(50) DEFAULT NULL COMMENT '新闻标题',
`keywords` VARCHAR(50) DEFAULT NULL COMMENT '关键词',
`author` VARCHAR(20) DEFAULT NULL COMMENT '作者',
`contents` TEXT COMMENT '内容',
`status` TINYINT(2) DEFAULT '1' COMMENT '状态 1:正常 0:删除',
`create_time` DATETIME DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8 COMMENT='新闻文章表';
创建演示数据,有针对向的向表里手工添加一条数据,注意contents字段尽可能的内容多写,然后使用sql 蠕虫复制(这种生成数据方式同样适用于数据表中有主键的情况)
INSERT INTO qs_news (title,keywords,author,contents,create_time) SELECT title,keywords,author,contents,create_time FROM qs_news;
2、读取慢日志文件
# vim /usr/local/mysql/log/qinser_slow.log
其中:# Time与 SET timestamp 表示慢查询SQL发生的日期时间, # Query_time:3.447456 表示此条语句执行的秒数。
3、慢查询工具mysqldumpslow
mysqldumpslow 是msyql自带的工具,位于/usr/local/mysql/bin/目录下,mysql安装成功后就可以全局使用。
# mysqldumpslow --help
# mysqldumpslow /usr/local/mysql/log/qinser-slow.log #查询所有
# mysqldumpslow -s r -t 10 /usr/local/mysql/log/qinser-slow.log #得到返回记录集最多的10个SQL
# mysqldumpslow -s c -t 10 /usr/local/mysql/log/qinser-slow.log #得到访问次数最多的10个SQL
# mysqldumpslow -s t -t 10 -g 'left join' /usr/local/mysql/log/qinser-slow.log #得到按照时间排序的前10条里面含有左连接的查询语句
# mysqldumpslow /usr/local/mysql/log/qinser-slow.log | more #建议在使用这些命令时结合 | 和more 使用 ,否则有可能出现刷屏的情况。
常用参数:
-s, 是表示按照何种方式排序,
c: 访问计数
l: 锁定时间
r: 返回记录
t: 查询时间
al:平均锁定时间
ar:平均返回记录数
at:平均查询时间
-t, 是top n的意思,即为返回前面多少条的数据;
-g, 后边可以写一个正则匹配模式,大小写不敏感的;
4、pt-query-digest工具的使用
需要自己安装pt-query-digest。pt-query-digest工具相较于mysqldumpslow功能多一点。
(1)安装
# yum -y install perl-DBI
# yum -y install perl-DBD-MySQL
# yum -y install perl-Time-HiRes
# yum -y install perl-IO-Socket-SSL
# yum -y install perl-Digest-MD5-2.52-3.el7.x86_64
# cd /mydata/
# wget percona.com/get/pt-query-digest
# chmod u+x pt-query-digest
# mv pt-query-digest /usr/bin/
# pt-query-digest --help #查看参数
(2)使用:
# pt-query-digest /usr/local/mysql/log/qinser-slow.log
查询结果分为三部分:
第一部分:显示出了日志的时间范围,以及总的sql数量和不同的sql数量
第二部分:显示出统计信息
第三部分:每一个sql具体的分析(与第一部分的Query ID 键值对应)
其中: pct是percent的简写,表示占的百分比,cout是占总sql个数的百分比,exec time 是占总执行时间的百分比,lock time 表示占总的锁表时间的百分比。 这三个数的比例越大,越需要关注。
(3)如何通过pt-query-digest 慢查询日志发现有问题的sql
1)查询次数多且每次查询占用时间长的sql:通常为pt-query-digest分析的前几个查询
2)IO消耗大的sql 注意pt-query-digest分析中的Rows examine项
3)为命中索引的sql
注意pt-query-digest分析中Rows examine(扫描行数) 和 Rows sent (发送行数)的对比 ,如果扫描行数远远大于发送行数,则说明索引命中率并不高。
四、对SQL进行优化
通过上面的慢查询,我们可以得到哪些sql语句执行的慢,然后对这些语句进行分析
1、使用explain查询sql的执行计划
# mysql -u root -p
# use ecshop
# explain select * from `qs_news` where contents like '%AAA%' and title like '%李四%';
+----+-------------+---------+------------+------+---------------+------+---------+------+-------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+---------+------------+------+---------------+------+---------+------+-------+----------+-------------+
| 1 | SIMPLE | qs_news | NULL | ALL | NULL | NULL | NULL | NULL | 41507 | 1.23 | Using where |
+----+-------------+---------+------------+------+---------------+------+---------+------+-------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
参数分析:
table:表示属于哪张数据表
type:最重要的参数,表示连接使用了何种类型。从最好到最差的连接类型为const,eq_reg,ref,range,index和ALL。
possible_keys:显示可能应用在这张表中的索引。如果为null,则表示没有可能的索引。
key:实际使用的索引。如果为null,则表示没有使用索引。
key_len:使用的索引的长度,在不损失精确性的情况下,长度越短越好。
ref:表示索引的哪一列被使用了,如果可能的话,是一个常数。
rows:Mysql认为必须检查的用来返回请求数据的行数。
2、count()和 Max()的优化方法
对于max()的字段建立索引,能加快查询。
3、对子查询的优化
4、group by 的优化
5、Limit的优化
五、对索引进行优化
1、选择合适的列建立索引
2、索引优化sql的方法
3、索引维护的方法
六、数据库结构优化
1、选择合适的数据类型
2、数据库表的范式化优化
3、数据库表的反范式优化
4、数据库表的垂直拆分
5、数据库表的水平拆分
七、系统配置优化
1、数据库系统配置优化
2、Mysql配置文件优化
3、第三方配置工具使用
八、服务器硬件优化