MySQL优化整体

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: MySQL优化整体

屏幕截图 2023-08-28 195743.png

目录

1.MySQL瓶颈优化(业务从小到大)

2.解决瓶颈:做索引 查询一些MySQL数据库的性能参数用show status

3.通过profiling命令得到更准确的SQL执行消耗系统资源的信息,profiling默认是关闭的。

4.优化表结构

5.分析表,检查表和优化表

1. 优化哲学

2. 优化工具介绍

3. 优化思路


1.MySQL瓶颈优化(业务从小到大)

假设一个网站从最开始访问量很小做到日PV千万,我们来推测一下它的mysql服务器架构演变过程。

第一阶段: 网站访问量日pv量级在1w以下。

   单台机器跑web和db,不需要做架构层调优(比如,不需要增加memcached缓存)。此时,数据往往都是每日冷备份的,但是有时候如果考虑数据安全性,会搭建一个mysql主从。

第二阶段: 网站访问量日pv达到几万。

   此时单台机器已经有点负载,需要我们把web和db分开,需要搭建memcached服务作为缓存。也就是说,在这个阶段,我们还可以使用单台机器跑mysql去承担整个网站的数据存储和查询。如果做mysql主从目的也是为了数据安全性。

第三阶段: 网站访问量日pv达到几十万。

   单台机器虽然也可以支撑,但是需要的机器配置要比之前的机器多好多。如果经费允许,可以购买配置很高的机器来跑mysql服务,但是并不是说,配置翻倍,到了一定阶段配置增加已经不能带来性能的增加。所以,此阶段,我们会想到做mysql服务的集群,也就是说我们可以拿多台机器跑mysql。但mysql的集群和web集群是不一样的,我们需要考虑数据的一致性,所以不能简单套用做web集群的方式。可以做的架构是,mysql主从,一主多从。为了保证架构的强壮和数据完整,主只能是一个,从可以是多个。还有一个问题,我们需要想到,就是在前端web层,我们程序里面指定了mysql机器的ip,那么当mysql机器有多台时,程序里面如何去配置?我们可以拿多台机器跑mysql,其中一台写,其他多台是读,我们只需要把读写的ip分别配置到程序中,程序自动会去区分机器。

第四阶段: 网站访问量日pv到几百万。

   之前的一主多从模式已经遇到瓶颈,因为当网站访问量变大,读数据库的量也会越来越大,我们需要多加一些从进来,但是从的数量增加到数十台时,由于主需要把bin-log全部分到所有从上,那么这个过程本身就是一件很繁琐读取,势必会造成从上同步过来的数据有很大延迟。所以,我们可以做一个优化,把mysql原来的一主多从为一主一从,然后作为其他从的主,而前面的主,只负责网站业务的写入,而后面的从不负责网站任何业务,只负责给其他从同步bin-log。这样还可以继续多叠加几个从库。

第五阶段: 网站访问量日pv到1千万的时候,我们发现,网站的写入量非常大,我们之前架构中只有一个主,这里的主已经成为瓶颈了。所以,需要再进一步作出调整,建议分布式

2.解决瓶颈:做索引 查询一些MySQL数据库的性能参数用show status

SHOW STATUS LIKE 'Connections'; //连接mysql服务器的次数
SHOW STATUS LIKE 'uptime'; //mysql服务器的上线时间
SHOW STATUS LIKE 'com_select'; //查询操作的次数
SHOW STATUS LIKE 'com_insert'; //插入操作的次数
SHOW STATUS LIKE 'com_update'; //更新操作的次数
SHOW STATUS LIKE 'com_delete'; //删除操作的次数
SHOW STATUS LIKE 'slow_queries'; //查询mysql服务器的慢查询次数
explain select * from city \G  //分析查询语句,或desc

索引提高了查询效率: Create index 索引名 on 表名(字段)

3.通过profiling命令得到更准确的SQL执行消耗系统资源的信息,profiling默认是关闭的。

查看profiling状态
show variables like '%profiling%';
select @@profiling;
打开profiling功能 
set profiling=1;
执行要测试的sql语句
select * from city where countrycode='CHN';
查看资源消耗
show profiles;
show profile for query 2;
完成后关闭
set profiling=0;

4.优化表结构

将字段很多的表分解成多个表

增加中间表

合理增加冗余字段

优化插入记录的速度 ***

(1)禁用索引(mysql 8.0支持)

ALTER TABLE city DISABLE KEYS;

(2)禁用唯一性检查

set unique_checks=0;

(3)使用批量插入

insert into fruits values ('x8','101','mongo2','5.5'),('x7','101','mongo2','5.5');

(4)使用load data infile批量插入

SET unique_checks=0;
SET foreign_key_checks=0;
set autocommit=0;
load data local infile 'data.txt' into table t1

5.分析表,检查表和优化表

(1)分析表:分析关键字的分布

ANALYZE TABLE city;

显示结果:

   Table是表名

   op执行的操作是什么

   msg_type 信息级别(status是正常状态,info是信息,note注意,warning警告,error错误)

   msg_text 是显示信息

(2)检查表:检查是否存在错误

CHECK TABLE city ;

(3)优化表:消除删除或更新造成的空间浪费

optimize table city \G

========================================================================

1. 优化哲学

1.1 优化有风险

复杂的生产环境

没有意识到优化的风险和后果

优化技术可能带来的后果,需要在控制范围内

稳定性和业务可持续性比性能更重要

优化变更有风险

性能变好,维持和变差是等概率事件

优化不能只是数据库管理员担当风险,所有的人分享优化成果

优化工作是由业务需要驱使的

1.2 优化的范围

存储、主机和操作系统:

   主机架构稳定性

   I/O规划及配置

   Swap

   OS内核参数

   网络问题    

应用 :(Index,lock,session)

   应用程序稳定性和性能

   SQL语句性能

   串行访问资源

   性能欠佳会话管理

数据库优化:(内存、数据库设计、参数)

   内存

   数据库结构(物理&逻辑)

   实例配置

2. 优化工具介绍

2.1 系统层

CPU :  计算(主)和调度(次)  

MEM :  缓存cache和缓冲buffer

IO  :  输入和输出

(1) top命令

%Cpu(s):  0.0 us, 0.0 sy, 100.0 id,  0.0 wa

id   空闲的CPU时间片占比

us   用户程序工作所占用的时间片占比

sy   内核工作花费的cpu时间片占比

过高的原因:

内核本身bug,建议centos7.6以上

并发很高

wa     cpu用来等待的时间片占比

IO

等待大的处理事件

KiB Mem :  4937752 total,  3988956 free,   476100 used,   472696 buff/cache   4193924 avail Mem

KiB Swap:  1048572 total,  1048572 free,        0 used.

(2) iostat

[root@db01 ~]# iostat -dk 1

一般情况下,CPU高,IO也应该高。

如果:CPU 高   ,IO 比较低

wait 高:  有可以能IO出问题了(Raid ,过度条带化)  

SyS  高:  有可能是锁的问题,需要进一步去数据库中判断

(3) vmstat

[root@db01 ~]# vmstat   1

2.2 数据库层工具

show status  
    show variables 
    show index  
    show processlist 
    show slave status
    show engine innodb status 
    desc /explain 
    slowlog

  扩展类深度优化:

pt系列(pt-query-digest pt-osc pt-index 等)
    mysqlslap 
    sysbench 
    information_schema (I_S)
    performance_schema (P_S)
    sys

3. 优化思路

3.0 未优化前的压力测试

create database hehe charset utf8mb4;
use hehe;
set sql_log_bin=0;
source t100w.sql
grant all on *.* to root@'localhost' identified by '123';
[root@db01 ~]# mysqlslap --defaults-file=/etc/my.cnf \
--concurrency=100 --iterations=1 --create-schema='world' \
--query="select * from world.t100w where k2='ABxy'" engine=innodb \
--number-of-queries=200 -uroot -p -verbose

3.1 主机,存储,网络

主机

真实的硬件(PC Server): DELL  R系列 ,华为,浪潮,HP,曙光,联想

云产品:ECS、数据库RDS、DRDS、PolarDB

IBM 小型机 P6  570  595   P7 720  750  780     P8

CPU根据数据库类型

OLTP  联机事务处理 增删改  ERP,CRM,OA

OLAP  联机分析处理 查询 数据统计分析

IO密集型:线上系统,OLTP主要是IO密集型的业务,高并发

CPU密集型:数据分析数据处理,OLAP,cpu密集型的,需要CPU高计算能力(i系列,IBM power系列)

CPU密集型: I 系列的,主频很高,核心少

IO密集型:  E系列(至强),主频相对低,核心数量多

内存

建议2-3倍cpu核心数量 (ECC)

磁盘选择

SATA-III   SAS    Fc    SSD(sata) pci-e ssd  Flash

主机 RAID卡的BBU(Battery Backup Unit)关闭

存储

根据存储数据种类的不同,选择不同的存储设备

配置合理的RAID级别(raid5、raid10、热备盘)  

r0 :条带化 ,性能高

r1 :镜像,安全

r5 :校验+条带化,安全较高+性能较高(读),写性能较低 (适合于读多写少)

r10:安全+性能都很高,最少四块盘,浪费一半的空间(高IO要求)

网络

1、硬件买好的(单卡单口)

2、网卡绑定(bonding),交换机堆叠

以上问题,提前规避掉。

3.2 系统

Swap调整

echo 0 >/proc/sys/vm/swappiness的内容改成0(临时),

vim /etc/sysctl.conf

上添加vm.swappiness=0(永久)

sysctl -p

IO调度策略

centos 7 默认是deadline

cat   /sys/block/sda/queue/scheduler

#临时修改为deadline(centos6)

echo deadline >/sys/block/sda/queue/scheduler

vi /boot/grub/grub.conf

更改到如下内容:

kernel /boot/vmlinuz-2.6.18-8.el5 ro root=LABEL=/ elevator=deadline rhgb quiet
IO :
    raid
    no lvm
    ext4或xfs
    ssd
    IO调度策略

提前规划好以上所有问题,减轻MySQL优化的难度。

3.3 数据库实例(参数)

3.3.1 Max_connections *****

(1)简介

Mysql的最大连接数,如果服务器的并发请求量比较大,可以调高这个值,当然这是要建立在机器能够支撑的情况下,因为如果连接数越来越多,mysql会为每个连接提供缓冲区,就会开销的越多的内存,所以需要适当的调整该值,不能随便去提高设值。

(2)判断依据

show variables like 'max_connections';
    +-----------------+-------+
    | Variable_name   | Value |
    +-----------------+-------+
    | max_connections | 151   |
    +-----------------+-------+
show status like 'Max_used_connections';
    +----------------------+-------+
    | Variable_name        | Value |
    +----------------------+-------+
    | Max_used_connections | 101   |
    +----------------------+-------+

(3)修改方式举例

vim /etc/my.cnf

Max_connections=1024

补充:

   1.开启数据库时,我们可以临时设置一个比较大的测试值

   2.观察show status like 'Max_used_connections';变化

   3.如果max_used_connections跟max_connections相同,

   那么就是max_connections设置过低或者超过服务器的负载上限了

3.3.2 back_log ***

(1)简介

mysql能暂存的连接数量,当主要mysql线程在一个很短时间内得到非常多的连接请求时候它就会起作用,如果mysql的连接数据达到max_connections时候,新来的请求将会被存在堆栈中,等待某一连接释放资源,该推栈的数量及back_log,如果等待连接的数量超过back_log,将不被授予连接资源。

back_log值指出在mysql暂时停止回答新请求之前的短时间内有多少个请求可以被存在推栈中,只有如果期望在一个短时间内有很多连接的时候需要增加它

(2)判断依据

show full processlist

发现大量的待连接进程时,就需要加大back_log或者加大max_connections的值

(3)修改方式举例

vim /etc/my.cnf

back_log=1024

3.3.3 wait_timeout和interactive_timeout ****

(1)简介

wait_timeout:指的是mysql在关闭一个非交互的连接之前所要等待的秒数

interactive_timeout:指的是mysql在关闭一个交互的连接之前所需要等待的秒数,比如我们在终端上进行mysql管理,使用的即使交互的连接,这时候,如果没有操作的时间超过了interactive_time设置的时间就会自动的断开,默认的是28800,可调优为7200。

wait_timeout:如果设置太小,那么连接关闭的就很快,从而使一些持久的连接不起作用

(2)设置建议

如果设置太大,容易造成连接打开时间过长,在show processlist时候,能看到很多的连接 ,一般希望wait_timeout尽可能低

(3)修改方式举例

wait_timeout=60

interactive_timeout=1200

长连接的应用,为了不去反复的回收和分配资源,降低额外的开销。

一般我们会将wait_timeout设定比较小,interactive_timeout要和应用开发人员沟通长链接的应用是否很多。如果他需要长链接,那么这个值可以不需要调整。

另外还可以使用类外的参数弥补。

3.3.4 key_buffer_size *****

(1) myisam 表的索引缓冲区

(2) 临时表的缓冲区

mysql> show status like "created_tmp%";
+-------------------------+-------+
| Variable_name           | Value |
+-------------------------+-------+
| Created_tmp_disk_tables | 0     |
| Created_tmp_files       | 6     |
| Created_tmp_tables      | 1     |
Created_tmp_tables/(Created_tmp_disk_tables + Created_tmp_tables)   越高越好
Created_tmp_disk_tables/(Created_tmp_disk_tables + Created_tmp_tables) 
Created_tmp_disk_tables/(Created_tmp_disk_tables + Created_tmp_tables)

控制在5%-10%以内

mysql> show variables like "key_buffer_size%";

3.3.5 query_cache_size

查询缓存简称QC,MySQL将查询结果存放在缓冲区

show variables like '%query_cache%';

query_cache_limit:超过此大小的查询将不缓存

query_cache_min_res_unit:缓存块的最小大小,默认是4KB,值大对大数据查询有好处,小数据查询容易造成内存碎片和浪费

query_cache_size:查询缓存大小,最小单位是1024byte

query_cache_type:缓存类型,值0关闭、值1缓存所有、值2仅缓存select语句中SQL_CACHE指定需要缓存的查询

vim /etc/my.cnf

query_cache_size=256M

query_cache_type=1

3.3.6 max_connect_errors

MySQL中与安全有关的计数器值,它负责阻止过多尝试失败的客户端以防止暴力破解密码的情况;

当超过指定次数,MYSQL服务器将禁止host的连接请求。

3.3.7 sort_buffer_size

connection级参数,每个需要进行排序的线程分配该大小的一个缓冲区。

增加值加速ORDER BY或GROUPBY操作,值过大容易耗尽内存。

3.3.8 max_allowed_packet

MySQL根据配置文件限制Server接受的数据包大小

有时候大的插入和更新会受 max_allowed_packet 参数限制,导致写入或者更新失败。

最大值是1GB,必须设置1024的倍数。

3.3.9  join_buffer_size    

用于表间关联缓存的大小

3.3.10 thread_cache_size

服务器线程缓存,处理客户的线程将会缓存起来以响应下一个客户而不是销毁;

设置规则如下:1GB 内存配置为8,2GB配置为16,3GB配置为32,4GB或更高内存,可配置更大。

3.3.11 innodb_buffer_pool_size

InnoDB使用该参数指定大小的内存来缓冲数据和索引;

单独的MySQL数据库,最大可设置成物理内存的80%。

3.3.12  innodb_flush_log_at_trx_commit

主要控制了innodb将log buffer中的数据写入日志文件并flush磁盘的时间点,取值分别为0、1、2三个。

0,表示当事务提交时,不做日志写入操作,而是每秒钟将log buffer中的数据写入日志文件并flush磁盘一次;

1,则在每秒钟或是每次事务的提交都会引起日志文件写入、flush磁盘的操作,确保了事务的ACID;

2,每次事务提交引起写入日志文件的动作,但每秒钟完成一次flush磁盘操作。

注:1安全,0、2快速

3.3.13 innodb_thread_concurrency    

设置innodb线程的并发数量,值为0表示不限制;

建议设置服务器的CPU核数或是cpu的核数的2倍,默认设置一般为8.

3.3.14 innodb_log_buffer_size

确定日志文件所用的内存大小,以M为单位。

缓冲区更大能提高性能,对于较大的事务,可以增大缓存大小。

3.3.15 innodb_log_file_size

确定数据日志文件的大小,以M为单位,更大的设置可以提高性能。

3.3.16 innodb_log_files_in_group

为提高性能,MySQL以循环方式将日志文件写到多个文件,推荐设置为3。

3.3.17 read_buffer_size  

MySql读入缓冲区大小,connection级参数

3.3.18  read_rnd_buffer_size  

MySql的随机读(查询操作)缓冲区大小,如果需要排序大量数据,可适当调高该值。

connection级参数

3.3.19  bulk_insert_buffer_size  

批量插入数据缓存大小,可以有效提高插入效率,默认为8M

3.3.20 binary log

binlog_cache_size=2M

为每个session 分配的内存,在事务过程中用来存储二进制日志的缓存,提高记录bin-log的效率。

没有什么大事务,dml也不是很频繁的情况下可以设置小一点;

如果事务大而且多,dml操作也频繁,则可以适当的调大一点。

max_binlog_cache_size = 8M     表示的是binlog 能够使用的最大cache内存大小

max_binlog_size = 512M         指定binlog日志文件的大小

expire_logs_days = 7           定义了mysql清除过期日志的时间

3.3.21 log_queries_not_using_indexes

开启记录所有没有经过索引的查询。

3.4 优化后的压力测试

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
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


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
29天前
|
SQL 关系型数据库 MySQL
大厂面试官:聊下 MySQL 慢查询优化、索引优化?
MySQL慢查询优化、索引优化,是必知必备,大厂面试高频,本文深入详解,建议收藏。关注【mikechen的互联网架构】,10年+BAT架构经验分享。
大厂面试官:聊下 MySQL 慢查询优化、索引优化?
|
5天前
|
缓存 关系型数据库 MySQL
MySQL 索引优化以及慢查询优化
通过本文的介绍,希望您能够深入理解MySQL索引优化和慢查询优化的方法,并在实际应用中灵活运用这些技术,提升数据库的整体性能。
41 18
|
4天前
|
缓存 关系型数据库 MySQL
MySQL 索引优化以及慢查询优化
通过本文的介绍,希望您能够深入理解MySQL索引优化和慢查询优化的方法,并在实际应用中灵活运用这些技术,提升数据库的整体性能。
15 7
|
3天前
|
缓存 关系型数据库 MySQL
MySQL 索引优化与慢查询优化:原理与实践
通过本文的介绍,希望您能够深入理解MySQL索引优化与慢查询优化的原理和实践方法,并在实际项目中灵活运用这些技术,提升数据库的整体性能。
21 5
|
1月前
|
SQL 关系型数据库 MySQL
MySQL慢查询优化、索引优化、以及表等优化详解
本文详细介绍了MySQL优化方案,包括索引优化、SQL慢查询优化和数据库表优化,帮助提升数据库性能。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
MySQL慢查询优化、索引优化、以及表等优化详解
|
22天前
|
关系型数据库 MySQL Java
MySQL索引优化与Java应用实践
【11月更文挑战第25天】在大数据量和高并发的业务场景下,MySQL数据库的索引优化是提升查询性能的关键。本文将深入探讨MySQL索引的多种类型、优化策略及其在Java应用中的实践,通过历史背景、业务场景、底层原理的介绍,并结合Java示例代码,帮助Java架构师更好地理解并应用这些技术。
23 2
|
1月前
|
缓存 监控 关系型数据库
如何优化MySQL查询速度?
如何优化MySQL查询速度?【10月更文挑战第31天】
76 3
|
1月前
|
缓存 关系型数据库 MySQL
如何优化 MySQL 数据库的性能?
【10月更文挑战第28天】
93 1
|
1月前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第27天】本文深入探讨了MySQL的索引策略和查询性能调优技巧。通过介绍B-Tree索引、哈希索引和全文索引等不同类型,以及如何创建和维护索引,结合实战案例分析查询执行计划,帮助读者掌握提升查询性能的方法。定期优化索引和调整查询语句是提高数据库性能的关键。
217 1
|
1月前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第26天】数据库作为现代应用系统的核心组件,其性能优化至关重要。本文主要探讨MySQL的索引策略与查询性能调优。通过合理创建索引(如B-Tree、复合索引)和优化查询语句(如使用EXPLAIN、优化分页查询),可以显著提升数据库的响应速度和稳定性。实践中还需定期审查慢查询日志,持续优化性能。
86 0