MySQL性能监控与调优

RPM包搜索网站:http://rpmfind.net/linux/RPM/index.html、http://rpm.pbone.net/、https://pkgs.org/
Percona官网:https://www.percona.com/

缓存优化

1、应用的持久层(模型层)开启缓存
2、使用Redis缓存

慢查询分析

慢查询:未使用索引的查询 和 超过指定时间的查询

慢查询相关参数
slow_query_log:是否开启慢查询日志
slow_query_log_file:慢查询日志路径,必须存在且mysql用户有写权限
long_query_time:慢查询阈值时间
log_queries_not_using_indexes:未使用索引的查询是否记入慢查询日志

查看参数:show variables like 'slow_query_log';
查看全局参数:show global variables like 'slow_query_log';
设置参数:set slow_query_log=on;
设置全局参数:set global slow_query_log=on;

慢日志格式

# Time: 执行时间
# User@Host: 用户信息
# Query_time: 查询耗时  Lock_time: 锁耗时 Rows_sent: 发送行数  Rows_examined: 扫描行数
SET timestamp=执行时间戳;
SQL语句

慢查询分析工具mysqldumpslow
耗时统计前三:mysqldumpslow -t 3 /var/lib/mysql/slow.log

慢查询分析工具pt-query-digest
pt-query-digest 包含在 Percona 公司提供的工具套装 percona-toolkit 中,依赖Perl
1、安装Perl
yum install -y perl-DBI
yum install -y perl-DBD-MySQL
yum install -y perl-Time-HiRes
yum install -y perl-IO-Socket-SSL
yum install -y perl-Digest-MD5
yum install -y perl-TermReadKey
2、安装percona-toolkit
到percona官网上找到 percona-toolkit
下载对应操作系统的percona-toolkit.rpm
安装:rpm -ivh percona-toolkit.rpm

前三耗时查询:pt-query-digest --limit 3 /var/lib/mysql/slow.log

执行计划分析

explain 查询语句; 得到该查询语句的执行计划
1、table:涉及的表
2、type:const(唯一索引查找)、eq_rep(唯一索引范围查找)、ref(基于索引的连接查询)、range(基于索引的范围查找)、index(索引扫描)、ALL(表扫描),性能由高到低
3、possible_key:可用索引
4、key:实际使用索引
5、key_len:索引长度,越短越好
6、ref:使用索引具体的列
7、row:必须扫描的行数

查询优化

MySql的索引由B+树实现

1、需要建立索引的字段
where从句、group by从句、order by从句、on从句中的字段
2、索引字段数量不能太多,索引字段长度越小越好
3、select max(age) from people;
age不是索引的话,需要扫描整张表,应该给age建立索引
4、用连接查询 代替 嵌套查询(需要建立临时表)
5、order by title limit 500,10
order by的字段必须是 索引字段,否则需要扫描整张表;
即使是索引字段排序,limit 500,10,前500条数据也需要索引扫描,可以改成 where title>前一页的最后一个title order by title limit 0,10
6、多字段索引,离散度高(重复少)的字段放在前面
7、联合索引最左匹配原则:key index_abc(a,b,c),查询时提供最左字段才能用到该联合索引,例如(a>0);只提供右侧字段则不会用到该联合索引,例如(b>0)、(b>0,c>0)

数据类型优化

1、text类型放到附加表中,需要的时候才查询
2、用int存储时间,用unix_timestamp()、from_unixtime()来转换
3、用bigint存IP,用inet_aton()、inet_ntoa()来转换

表设计优化

1、范式设计
2、增加冗余字段,来减少连接查询
3、垂直拆分

系统配置优化

/etc/security/limits.conf

soft nofile 65535   # 最大打开文件数,默认为1024
hard nofile 65535

查看限制:ulimit -a

MySQL配置优化

/etc/my.cnf

Innodb_buffer_pool_size=内存的75%  # 如果系统中只有Innodb表
Innodb_buffer_pool_instances=4  # 缓冲池个数
Innodb_flush_log_at_trx_commit=2 # 每2次提交,从缓冲区刷新到磁盘,默认为1
Innodb_read_io_threads=4  # MySQL很多操作只能单线程,MySQL性能对CUP核数不敏感
Innodb_write_io_threads=4  # 根据CPU数和读写比率去掉
Innodb_file_per_table=on # 每个表使用独立表空间,默认为OFF(使用共享表空间)

Percona的MySQL配置生成器:https://tools.percona.com/wizard

预防SQL注入

1、JDBC防止SQL注入
使用 java.sql.Preparedstatement

string sql = "select * from people p where p.id = ? and p.name = ?";
PreparedStatement  ps = connection.prepareStatement(sql);
ps.setInt(1,id);
ps.setString(2,name);
ResultSet rs = ps.executeQuery(); 

原理
PreparedStatement使用了MySQL支持的预编译功能,语句和参数分开提交
连接池要指定开启预编译:jdbc:mysql://localhost:3306/db1?&useServerPrepStmts=true&cachePrepStmts=true

MySQL预编译

prepare  statement_1 from 'select * from user where username like ?';
set @username='%小宋%';
execute statement_1 using @username;

2、MyBatis防止SQL注入

用 #{} 来引用参数,  而非 '${}'。使用'${}'时,要过滤参数里的危险字符
#{} 下层调用了PreparedStatement 

你可能感兴趣的:(MySQL性能监控与调优)