第二十一章 MySQL数据库优化

一、数据硬件优化(选型)

1.数据库选择

1.真实的硬件物理机,虚拟化,搭建数据库
2.云服务器ECS,自己搭建数据库
3.云数据库(RDS,DRDS)

2.数据库类型

1.OLTP	在线事务处理系统,支持大量的并发用户修改数据
2.OLAP	数据仓库,数据展示,数据的分析(非关系型数据库)

3.硬件选择

1)CPU选型

1.IO密集型:线上,OLTP主要就是IO密集型,支持高并发,E系列
2.CPU密集型:I系列,数据分析处理,CPU计算能力很高

2)内存

1.内存不是越大越好,内存越大,使用一定越多,浪费越多,命中率反而降低
2.一般内存是CPU核心数量的2-3倍
	4核  12G内存
	8核	24G内存

3)磁盘选择

1.SATA盘
2.SSD盘
3.SAS盘

4)存储选择

1.本地SSD盘
2.云盘

5)网络选择

1.硬件服务器,网卡最好买单卡单口
2.网卡绑定

4.操作系统的优化

1)操作系统优化

[root@db03 ~]# cat /etc/sysctl.conf 
net.ipv4.tcp_fin_timeout = 2
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_keepalive_time = 600
net.ipv4.ip_local_port_range = 4000    65000
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_max_tw_buckets = 36000
net.ipv4.route.gc_timeout = 100
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_synack_retries = 1
net.core.somaxconn = 16384
net.core.netdev_max_backlog = 16384
net.ipv4.tcp_max_orphans = 16384
net.ipv4.ip_forward = 1

2)swap空间利用调整

#swap空间的利用率,值越大,越可能使用swap空间[root@db03 ~]# cat /proc/sys/vm/swappiness 30#配置成最小值(临时设置)[root@db03 ~]# echo 0 > /proc/sys/vm/swappiness[root@db03 ~]# cat /proc/sys/vm/swappiness 0#永久设置[root@db03 ~]# cat /etc/sysctl.conf vm.swappiness = 0

3)IO调度策略

#调度策略文件[root@db03 ~]# cat /sys/block/sda/queue/scheduler noop deadline [cfq]#修改调度策略[root@db03 ~]# echo deadline > /sys/block/sda/queue/scheduler [root@db03 ~]# cat /sys/block/sda/queue/scheduler noop [deadline] cfq

二、数据库数据查询

1.创建数据库数据

#创建数据库mysql> create database devtest;Query OK, 1 row affected (0.00 sec)#创建表mysql> create table test(id int(11),num int(11),k1 char(2),k2 char(4),dt timestamp not null);Query OK, 0 rows affected (0.00 sec)#插入100万的数据delimiter //create procedure rand_data(in num int)begindeclare str char(62) default 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';declare str2 char(2);declare str4 char(4);declare i int default 0;while i<num doset str2=concat(substring(str,1+floor(rand()*61),1),substring(str,1+floor(rand()*61),1));set str4=concat(substring(str,1+floor(rand()*61),2),substring(str,1+floor(rand()*61),2));set i=i+1;insert into test values(i,floor(rand()*num),str2,str4,now());end while;end;//mysql> d ;mysql> call rand_data(1000000);

2.查看数据可用性

#查看数据量
mysql> select count(*) from test;
+----------+
| count(*) |
+----------+
|  1000000 |
+----------+
1 row in set (0.24 sec)

#查看数据内容
mysql> select * from test limit 10;
+------+--------+------+------+---------------------+
| id   | num    | k1   | k2   | dt                  |
+------+--------+------+------+---------------------+
|    1 | 862115 | xl   | UVno | 2020-11-12 18:00:21 |
|    2 | 557819 | MI   | 4512 | 2020-11-12 18:00:21 |
|    3 | 290215 | nA   | HIxy | 2020-11-12 18:00:21 |
|    4 | 517425 | sM   | qrCD | 2020-11-12 18:00:21 |
|    5 | 680528 | lv   | noef | 2020-11-12 18:00:21 |
|    6 |  44996 | l3   | 23ST | 2020-11-12 18:00:21 |
|    7 |   1334 | a6   | MNxy | 2020-11-12 18:00:21 |
|    8 |  33982 | 1r   | YZst | 2020-11-12 18:00:21 |
|    9 | 799722 | pl   | klpq | 2020-11-12 18:00:21 |
|   10 | 333293 | nR   | 45zA | 2020-11-12 18:00:21 |
+------+--------+------+------+---------------------+
10 rows in set (0.01 sec)

3.压力测试

mysqlslap --defaults-file=/etc/my.cnf 
--concurrency=100 --iterations=1 --create-schema='devtest' 
--query="select * from devtest.test where num='698623'" engine=innodb 
--number-of-queries=20000 -uroot -p123 -verbose

三、数据库优化参数

1.最大连接数 max_connections

1.简介
MySQL的最大连接数,增加该值增加mysqld 要求的文件描述符的数量。如果服务器的并发连接请求量比较大,建议调高此值,以增加并行连接数量,当然这建立在机器能支撑的情况下,因为如果连接数越多,介于MySQL会为每个连接提供连接缓冲区,就会开销越多的内存,所以要适当调整该值,不能盲目提高设值。

2.查看方式
#查看最大连接数
mysql> show variables like 'max_connection';
#查看已经使用的连接数
mysql> show status like 'max_used_connections';

3.一般配置
max_connections=1024

4.如何判断该配置多少
	1)先给一个比较大的值
	2)业务高峰期,查看已经使用的数量
	3)如果max_used_connections远远小于max_connection则降低配置

2.连接队列 back_log

1.简介
back_log值指出在MySQL暂时停止回答新请求之前的短时间内多少个请求可以被存在堆栈中。也就是说,如果MySql的连接数达到max_connections时,新来的请求将会被存在堆栈中,以等待某一连接释放资源,该堆栈的数量即back_log,如果等待连接的数量超过back_log,将不被授予连接资源

2.查看方式
mysql> show variables like 'back_log';
mysql> select @@back_log;

3.如何配置
back_log=1024

3.超时时间 wait_timeout和interactive_timeout

1.简介
wait_timeout和interactive_timeout都是指不活跃的连接超时时间,连接线程启动的时候wait_timeout会根据是交互模式还是非交互模式被设置为这两个值中的一个。如果我们运行mysql -uroot -p命令登陆到mysql,wait_timeout就会被设置为interactive_timeout的值。如果我们在wait_timeout时间内没有进行任何操作,那么再次操作的时候就会提示超时,这是mysql client会重新连接。
如果时间太长,show processlist得到的连接结果会很多,会造成资源的浪费

2.查看方式
mysql> select @@wait_timeout;
mysql> show variables like 'wait_timeout';
mysql> show variables like 'interactive_timeout';

3.一般配置
wait_timeout=60
interactive_timeout=7200

4.索引缓冲区 key_buffer_size

1.简介
key_buffer_size是对MyISAM表性能影响最大的一个参数,这个参数影响的是索引的读取速度

2.查看方式(默认是8M)
mysql> show variables like 'key_buffer_size';
#查看有多少索引走缓冲器
mysql> show status like '%key_read%';

3.一般设置
key_buffer_size=16M

5.查询缓冲区 query_cache_size

1.简介
MySQL的该功能是没有启动的,可能你通过show variables like '%query_cache%',会发现其变量have_query_cache的值是yes,MYSQL初学者很容易以为这个参数为YES就代表开启了查询缓存,实际上是不对的,该参数表示当前版本的MYSQL是否支持Query Cache,实际上是否开启查询缓存是看另外一个参数的值:query_cache_size ,该值为0,表示禁用query cache,而默认配置正是配置为0。

2.查看方式
#查看缓存查询是否开启
mysql> show variables like '%query_cache%';
#测试能否缓存查询
mysql> show status like '%Qcache%';
+-------------------------+---------+
| Variable_name           | Value   |
+-------------------------+---------+
| Qcache_free_blocks      | 1       |	#缓存中目前剩余的blocks数量(如果值较大,则查询缓存中的内存碎片过多)
| Qcache_free_memory      | 1031352 |	#空闲缓存的内存大小
| Qcache_hits             | 0       |	#命中缓存次数
| Qcache_inserts          | 0       |	#未命中然后插入次数
| Qcache_lowmem_prunes    | 0       |	#查询因为内存不足而被移除出查询缓存记录
| Qcache_not_cached       | 47199   |	#没有被缓存的查询数量
| Qcache_queries_in_cache | 0       |	#当前缓存中缓存的查询数量
| Qcache_total_blocks     | 1       |	#当前缓存的block数量
+-------------------------+---------+

3.一般配置
query_cache_size=64M
query_cache_type=1		#开启查询缓存
query_cache_limit=50M	#缓存的限制大小

6.错误连接最大次数 max_connect_errors

1.简介
max_connect_errors是MySQL的安全参数,阻止暴力破解数据库密码,超过设置的错误次数,锁定该用户或主机

2.查看方式
mysql> show variables like '%connect_errors%';

3.一般配置
max_connect_errors=20

7.sort_buffer_size

1.简介
数据需要进行排序时,查询结果的缓冲区
order by,group by,distinct

2.查看方式
mysql> show variables like '%sort_buffer_size%';
+-------------------------+---------+
| Variable_name           | Value   |
+-------------------------+---------+
| innodb_sort_buffer_size | 1048576 |
| myisam_sort_buffer_size | 8388608 |
| sort_buffer_size        | 262144  |
+-------------------------+---------+

3.一般设置
sort_buffer_size=2M

8.数据包限制 max_allowed_packet

1.简介
指代mysql服务器端和客户端在一次传送数据包的过程当中最大允许的数据包大小

2.查看方式
mysql> show variables like '%max_allowed_packet%';
+--------------------------+------------+
| Variable_name            | Value      |
+--------------------------+------------+
| max_allowed_packet       | 4194304    |
| slave_max_allowed_packet | 1073741824 |
+--------------------------+------------+

3.一般配置
max_allowed_packet=32M

9.join_buffer_size

1.简介
数据需要使用join语句时,查询结果的缓冲区

2.查看方式
mysql> show variables like 'join_buffer_size';
+------------------+--------+
| Variable_name    | Value  |
+------------------+--------+
| join_buffer_size | 262144 |
+------------------+--------+

3.一般设置
join_buffer_size=2M

10.thread_cache_size

1.简介
当客户端断开之后,服务器处理此客户的线程将会缓存起来以响应下一个客户而不是销毁(前提是缓存数未达上限)
即可以重新利用保存在缓存中线程的数量,当断开连接时如果缓存中还有空间,那么客户端的线程将被放到缓存中,如果线程重新被请求,那么请求将从缓存中读取,如果缓存中是空的或者是新的请求,那么这个线程将被重新创建,如果有很多新的线程,增加这个值可以改善系统性能。

2.查看方式
mysql> show variables like 'thread_cache_size';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| thread_cache_size | 9     |
+-------------------+-------+

3.一般设置
thread_cache_size=200

4.配置依据
#查看试图连接到mysql的链接数
mysql> show status like '%thread_%';
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| Threads_cached           | 9     |	#当前线程的空闲数
| Threads_connected        | 94    |	#正在连接的线程数
| Threads_created          | 107   |	#曾经达到过最大的链接线程数
| Threads_running          | 86    |	#活跃线程数
+--------------------------+-------+

11.innodb_buffer_pool_size

1.简介
innodb_buffer_pool_size参数对于innodb存储引擎的库设置缓存
pool_size缓存池的大小,包含索引和数据

2.查看方式
mysql> show variables like 'innodb_buffer_pool_size';
+-------------------------+-----------+
| Variable_name           | Value     |
+-------------------------+-----------+
| innodb_buffer_pool_size | 134217728 |
+-------------------------+-----------+

3.配置方式(数据库服务器总内存的70%-80%)
innodb_buffer_pool_size=800M

12.innodb_flush_log_at_trx_commit

1.简介
#双一标准的其中一个(默认是1)
  innodb_flush_log_at_trx_commit=1,用于控制redo log buffer中数据写入磁盘redo log文件的。
  	1:1代表在commit命令后会立即把redo log buffer,递交到操作系统内存中,然后由操作系统再立即写入到磁盘的redo log文件中
  	0:0代表每秒执行一次把redo log buffer递交到操作系统内存,操作系统内存也每秒往redo log中写入一次。
  	2:2代表每次commit后立即把redo log buffer数据递交到操作系统内存,然后操作系统每秒往redo log中写入一次
   #2和0一样,只不过能好一点,如果只是mysql服务宕机的话,提交到操作系统内存的事务还不会丢失。
#双一表中的另一个
  sync_binlog=1    每次事务递交都立即把二进制日志刷写到磁盘。
#双一标准都是用来控制mysql内存数据刷写到磁盘的频率,一个用来控制redo log, 一个用来控制二进制日志的

2.查看方式
mysql> show variables like 'innodb_flush_log_at_trx_commit';
+--------------------------------+-------+
| Variable_name                  | Value |
+--------------------------------+-------+
| innodb_flush_log_at_trx_commit | 1     |
+--------------------------------+-------+

3.一般配置
innodb_flush_log_at_trx_commit=1
sync_binlog=1

13.innodb_log_buffer_size

1.简介
日志文件的缓冲区大小

2.查看方式
mysql> show variables like 'innodb_log_buffer_size';
+------------------------+---------+
| Variable_name          | Value   |
+------------------------+---------+
| innodb_log_buffer_size | 8388608 |
+------------------------+---------+

3.一般设置
innodb_log_buffer_size=32M

14.innodb_log_file_size

1.简介
磁盘上日志文件的大小
[root@db01 ~]# ll /usr/local/mysql/data/ib_logfile*
-rw-rw---- 1 mysql mysql 50331648 11月 12 19:49 /usr/local/mysql/data/ib_logfile0
-rw-rw---- 1 mysql mysql 50331648 11月 12 18:06 /usr/local/mysql/data/ib_logfile1

2.查看方式
mysql> show variables like 'innodb_log_file_size';
+----------------------+----------+
| Variable_name        | Value    |
+----------------------+----------+
| innodb_log_file_size | 50331648 |
+----------------------+----------+

3.一般配置
innodb_log_file_size=128M

15.innodb_log_files_in_group

1.简介
将log文件分组,循环的方式写入多个文件,值是多少就有几个ib_logfile文件

2.查看方式
mysql> show variables like 'innodb_log_files_in_group';
+---------------------------+-------+
| Variable_name             | Value |
+---------------------------+-------+
| innodb_log_files_in_group | 2     |
+---------------------------+-------+

3.一般设置
innodb_log_files_in_group=3

16.read_buffer_size

1.简介
mysql读数据的缓冲区大小
设置以顺序扫描的方式扫描表数据的时候使用缓冲区的大小. 
每个线程进行顺序扫描的时候都会产生该buffer ,而且同一个Query中如果有多个表进行全表扫描,会产生多个该buffer

2.查看方式
mysql> show variables like 'read_buffer_size';
+------------------+--------+
| Variable_name    | Value  |
+------------------+--------+
| read_buffer_size | 131072 |
+------------------+--------+

3.一般配置
read_buffer_size=2M

17.read_rnd_buffer_size

1.简介
read_rnd_buffer_size是很重要的参数,尤其工作在如下场景:
       * sort_buffer中存的是行指针而不是要查询的数据。
       * 查询的字段中包含Blob/Text字段。
       * sort后有大量的数据行(limit 10并不能帮助你,因为MySQL是通过指针获取行数据的)
     如果你取出很少字段的数据(小于max_length_for_sort_data),行数据将会全部存储在sort buffer里,因此将不需要read_rnd_buffer_size这个参数。
     而如果你查询的字段数据很长(这些字段很可能含有Text/Blob字段),比max_length_for_sort_data还长,read_rnd_buffer_size这个参数将派上用场。

2.查看方式
mysql> show variables like 'read_rnd_buffer_size';
+----------------------+--------+
| Variable_name        | Value  |
+----------------------+--------+
| read_rnd_buffer_size | 262144 |
+----------------------+--------+

3.一般配置
read_rnd_buffer_size=2M

18.数据库优化配置

[mysqld]
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
socket=/tmp/mysql.sock
log-error=mysql.err
log_bin=mysql-bin
binlog_format=row
skip-name-resolve
server-id=1
log-slave-updates=1
relay_log_purge=0
max_connections=1024
back_log=128
wait_timeout=60
interactive_timeout=7200
key_buffer_size=16M
query_cache_size=64M
query_cache_type=1
query_cache_limit=50M
max_connect_errors=20
sort_buffer_size=2M
max_allowed_packet=32M
join_buffer_size=2M
thread_cache_size=200
innodb_buffer_pool_size=1024M
innodb_flush_log_at_trx_commit=1
sync_binlog=1
innodb_log_buffer_size=32M
innodb_log_file_size=128M
innodb_log_files_in_group=3
binlog_cache_size=2M
max_binlog_cache_size=8M
max_binlog_size=512M
expire_logs_days=7
read_buffer_size=2M
read_rnd_buffer_size=2M
bulk_insert_buffer_size=8M
[client]
socket=/tmp/mysql.sock
#单位转换
基本概念
       bit(位,又名“比特”):bit的缩写是b,是计算机中的最小数据单位(属于二进制的范畴,其实就是0或者1)
       Byte(字节):Byte的缩写是B,是计算机文件大小的基本计算单位。比如一个字符就是1Byte,如果是汉字,则是2Byte。
换算
     1B(字节)=8b(位)
     1 KB = 1024 B
     1 MB = 1024 KB
     1 GB = 1024 MB
     1TB = 1024GB

四、优化结果

1.没有优化前

[root@db01 ~]# mysqlslap --defaults-file=/etc/my.cnf --concurrency=100 --iterations=1 --create-schema='devtest' --query="select * from devtest.test where num='698623'" engine=innodb --number-of-queries=20000 -uroot -verbose 
Benchmark                      
	Running for engine rbose
	Average number of seconds to run all queries: 5456.335 seconds
	Minimum number of seconds to run all queries: 5456.335 seconds
	Maximum number of seconds to run all queries: 5456.335 seconds
	Number of clients running queries: 100
	Average number of queries per client: 200

2.优化后结果

#1.第一次查询
[root@db02 ~]# mysqlslap --defaults-file=/etc/my.cnf --concurrency=100 --iterations=1 --create-schema='devtest' --query="select * from devtest.test where num='698623'" engine=innodb --number-of-queries=20000 -uroot -verbose
Benchmark
	Running for engine rbose
	Average number of seconds to run all queries: 63.146 seconds
	Minimum number of seconds to run all queries: 63.146 seconds
	Maximum number of seconds to run all queries: 63.146 seconds
	Number of clients running queries: 100
	Average number of queries per client: 200
	
#2.第二次查询
[root@db02 ~]# mysqlslap --defaults-file=/etc/my.cnf --concurrency=100 --iterations=1 --create-schema='devtest' --query="select * from devtest.test where num='698623'" engine=innodb --number-of-queries=20000 -uroot -verbose
Benchmark
	Running for engine rbose
	Average number of seconds to run all queries: 0.787 seconds
	Minimum number of seconds to run all queries: 0.787 seconds
	Maximum number of seconds to run all queries: 0.787 seconds
	Number of clients running queries: 100
	Average number of queries per client: 200
原文地址:https://www.cnblogs.com/jhno1/p/15324326.html