MySQL调优01 - 单库调优思想

单库调优

文章目录

  • 单库调优
    • 一:系统中性能优化的核心思维
    • 二:MySQL性能优化实践
      • 1:连接层的优化
        • 1.1:连接数是越大越好吗?
        • 1.2:偶发高峰类业务的连接数配置
        • 1.3:分库分表情况下的连接数配置
        • 1.4:小结
      • 2:结构的优化
        • 2.1:表结构的优化
        • 2.2:字段结构的优化
        • 2.3:索引结构的优化
      • 3:参数的优化方案
      • 4:架构和SQL优化
        • 4.1:引入缓存中间件解决读压力
        • 4.2:引入消息中间件解决写压力
        • 4.3:MySQL架构优化
          • 主从架构
          • 双主双写架构
          • 分库分表

一:系统中性能优化的核心思维

  • 单个节点的性能表现,逃不过和CPU,内存和磁盘打交道。【最大利用率在80% - 85%最佳】
  • 优秀且使用的架构胜过千万次调优
  • 读写参半中项目集群和双主热备,写大于读引入消息中间件MQ,读大于写引入缓存redis/或者es,动静分离,读写分离
  • 预防大于一切,不要卡点设计,不要出现问题的时候再进行考虑
  • 无需追求完美,要理性的权衡利弊。
  • 步骤:发现问题瓶颈 -> 排查瓶颈原因 -> 定位瓶颈的位置 -> 解决性能瓶颈

在这里插入图片描述

二:MySQL性能优化实践

① 客户端与连接层的优化:调整客户端DB连接池的参数和DB连接层的参数。

② MySQL结构的优化:合理的设计库表结构,表中字段根据业务选择合适的数据类型、索引。

③ MySQL参数优化:调整参数的默认值,根据业务将各类参数调整到合适的大小。

④ 整体架构优化:引入中间件减轻数据库压力,优化MySQL架构提高可用性。

⑤ 编码层优化:根据库表结构、索引结构优化业务SQL语句,提高索引命中率。

纵观现在MySQL中的各类优化手段,基本上都是围绕着上述的五个维度展开

这五个性能优化项中,通常情况下,带来的性能收益排序为④ > ② > ⑤ > ③ > ①,不过带来的性能收益越大,也就意味着成本会更高。

1:连接层的优化

1.1:连接数是越大越好吗?

一个客户端连接是一条线程,那数据库的最大连接数调整到1W,岂不是代表着同时可以支持1W个客户端同时操作啦?

在不考虑硬件的情况下确实如此,但结合硬件来看待,就不行了

数据库连接数越大,也就意味着内部创建出的工作线程会越多,线程越多代表需要的CPU配置得更高

比如现在有300个客户端连接,内部创建了300条工作线程处理,但服务器的CPU仅有32个核心,那当前服务器最多只能支持32条线程同时工作

其他268条线程怎么办呢?为了其他线程能够正常执行,CPU就会以时间片调度的模式工作,不同核心在不同线程间反复切换执行

由于线程数远超核心数,因此会导致线程上下文切换的开销,远大于线程执行的开销。

数据库的连接数该设置成多少合适呢?

对于MySQL连接池的最大连接数,这点无需咱们关心,重点调整的是客户端连接池的连接数,原因如下:

  • MySQL实例一般情况下只为单个项目提供服务,你把应用程序那边的连接数做了限制,自然也就限制了服务端的连接数
  • 同时,不将MySQL的最大连接数和客户端连接池的最大连接数保持的一致的原因是有可能数据库实例不仅仅只为单个项目提供服务,比如你有时候会通过终端工具远程连接MySQL,如果你将两个连接池的连接数保持一致,就很有可能导致MySQL连接数爆满,最终造成终端无法连上MySQL。

而对于设置大小,对于几乎所有的数据库有一个通用的公式:最大连接数 = (CPU核心数 * 2) + 有效磁盘数(SSD固态硬盘的个数)

注意事项

  • C3P0、DBCP、Druid、HikariCP…等连接池的底层本质上是一个线程池,对于线程池而言,想要处理足够高的并发,那应该再配备一个较大的等待队列,也就是当目前池中无可用连接时,其他的用户请求/待执行的SQL语句则会加入队列中阻塞等待
  • 实际业务中,还需要考虑SQL的执行时长,比如一类业务的SQL执行只需10ms,而另一类SQL由于业务过为繁琐,每次调用时会产生一个大事务,一次执行下来可能需要5s+,那这两种情况都采用相同的连接池可以吗?可以是可以,但大事务会影响其他正常的SQL,因此想要完美的解决这类问题,最好再单独开一个连接池,为大事务或执行耗时较长的SQL提供服务
1.2:偶发高峰类业务的连接数配置

对于这类业务,常驻线程数不适合太多,因为并发来临时会导致创建大量连接,而并发过后一直保持数据库连接会导致资源被占用

所以对于类似的业务,可以将最大连接数按之前的公式配置,而常驻连接数则可以配成CPU核数+1,同时缩短连接的存活时间

及时释放空闲的数据库连接,以此确保资源的合理分配。

1.3:分库分表情况下的连接数配置

在数据库部署了多节点的情况下,要记得根据每个节点的硬件配置,来规划出合理的连接数。

1.4:小结

连接层的调优,实际上是指调整它的参数,即常驻连接数、最大连接数、空闲连接存活时间以及等待队列的容量

对于最佳连接数的计算,首先要把CPU核数放首位考虑,紧接着是磁盘,最后是网络带宽

  • 因为带宽会影响SQL执行时间,综合考虑后才能计算出最合适的连接数大小。

2:结构的优化

结构就是表结构,字段结构和索引结构

2.1:表结构的优化
  • 表结构设计时的第一条也是最重要的一条,字段数量一定不要太多
    • 正常情况下应当遵循第三范式(3NF)的原则设计,尽可能的根据业务将表结构拆分的更为精细化
      • 一方面能够确保内存中缓存的数据更多,同时也更便于维护
      • 另一方法精细的SQL表可以使得SQL语句效率更高
    • 一张表最多最多只能允许设计30个字段左右,否则会导致查询时的性能明显下降。
  • 允许必要的冗余字段,即必要条件下可以满足反范式
    • 不要无脑冗余
    • 最大好处是能够减少连表查询次数,用空间换时间的思想
  • 主键的选择一定要合适
    • 首先一张表中必须要有主键,其次主键最好是顺序递增的数值类型,最好为int类型
    • 迫不得已的情况下,再考虑使用其他类型的字段作为主键,但也至少需要保持递增性,例如雪花算法,而不是UUID
  • 对于实时性要求不高的数据建立中间表
    • 切记要实时性不高
    • 中间表可以一定程度上减小连表查询的开销,同时也能进一步提升查询速度
  • 根据业务特性为每张不同的表选择合适的存储引擎
    • 正常的表都选择InnoDB
    • 很少发生变更的表,就可以选择MyISAM引擎,比如字典表、标签表、权限表…
      在这里插入图片描述
2.2:字段结构的优化
  • 在保证足够使用的范围内,选择最小数据类型,因为它们会占用更少的磁盘、内存和CPU缓存,同时在处理速度也会更快。
  • 尽量避免索引字段值为NULL,定义字段时应尽可能使用NOT NULL关键字,因为字段空值过多会影响索引性能。
  • 在条件允许的情况下,尽量使用最简单的类型代替复杂的类型,因为简单的数据类型,操作时通常需要的CPU资源更少。
2.3:索引结构的优化
  • 索引字段的组成尽量选择多个

    • 如果一个表中需要建立多个索引,应适当根据业务去将多个单列索引组合成一个联合索引
      • 可以节省磁盘空间
      • 可以充分使用索引覆盖的方式查询数据,能够在一定程度上提升数据库的整体性能。
  • 对一个值较长的字段建立索引时,尽量建立前缀索引,而不是通过完整的字段值建立索引

    • 索引字段值越小,单个节点中能存储的索引键会越多,一个节点存下的索引键越多,索引树会越矮,查询性能自然会越高
  • 索引类型的选择一定要合理

    • 对于经常做模糊查询的字段,可以建立全文索引来代替普通索引
      • 基于普通索引做like查询会导致索引失效
      • 采用全文索引的方式做模糊查询效率会更高更快,并且全文索引的功能更为强大。
  • 索引结构的选择可以根据业务进行调整

    • 在某些不会做范围查询的字段上建立索引时,可以选用hash结构代替B+Tree结构
      • Hash结构的索引是所有数据结构中最快的,散列度足够的情况下,复杂度仅为O(1)。

在这里插入图片描述

3:参数的优化方案

这个一般是专业的数据库人员做的,了解一下就好

在这里插入图片描述

4:架构和SQL优化

4.1:引入缓存中间件解决读压力

正常的项目业务中,往往读请求的数量远超写请求,如果将所有的读请求都落入数据库处理,这自然会对MySQL造成巨大的访问压力,严重的情况下甚至会由于流量过大,直接将数据库打到宕机

为了解决这系列问题,通常都会在应用程序和数据库之间架设一个缓存,例如最常用的Redis

在这里插入图片描述

4.2:引入消息中间件解决写压力

redis只能解决读操作频繁的问题,对于写操作频繁的操作可以使用MQ进行削峰填谷:

在这里插入图片描述

4.3:MySQL架构优化

Redis也好,MQ也罢,这都属于在MySQL之前架设中间件,以此来减少真正抵达数据库的请求数量

但打铁还需自身硬,万一经过Redis、MQ后,那些必须要走MySQL执行的请求依旧超出单机MySQL的承载范围时,如若MySQL依旧以单机形式在线上运行,这绝对会导致线上频繁宕机的情况出现。

MySQL架构优化方案一般有三种:主从架构、双主架构、分库分表架构。

主从架构

适合读大于写的情况
在这里插入图片描述

主节点的数据变更后,从节点也会基于bin-log日志去同步数据,但这种模式下会存在些许的数据不一致性,因为同步是需要时间的

向主节点修改一条数据后,立马去从节点中查询,这时不一定能够看到最新的数据,因为这时数据也许还未被同步过来。

所以,选择用这种方案来提升性能,必然也会出现些许问题,这也是你必须要接受的,如果项目业务对数据实时性要求特别高,哪就不要考虑主从架构

双主双写架构

适合写大于读的场景

在这里插入图片描述
两个节点互为主从,两者之间相互同步数据,同时都具备处理读/写请求的能力,当出现读/写操作时,可以将请求抛给其中任意一个节点处理。

⚠️ 为了兼容两者之间的数据,对于每张表的主键要处理好,如果表的主键是int自增类型的,请一定要手动设置一下自增步长和起始值

可以将步长设置为2,起始值分别为1、2,这样做的好处是啥?能够确保主键的唯一性,设置后两个节点自增ID的序列如下:

  • 节点1:[1、3、5、7、9、11、13、15、17、19…]
  • 节点2:[2、4、6、8、10、12、14、16、18、20…]

当插入数据的SQL语句发往节点1时,会按照奇数序列自增ID,发往节点2时会以偶数序列自增ID,然后双方相互同步数据,最终两个MySQL节点都会具备完整的数据,因此后续的读请求,无论发往哪个节点都可以读到数据。

既然可以双主,为何为三主,四主?

当然可以,不过没必要这么做,因为当需要上三主、四主…的项目,直接就做分库分表更实在,而且这种多主模式存在一个很大的弊端就是存储容量的上限+木桶效应,多主模式中的每个节点都会存储完整的数据,因此当数据增长达到硬件的最大容量时,就无法继续写入数据了,此时只能通过加大磁盘的形式进一步提高存储容量,但硬件也不可能无限制的加下去,而且由于多主是基于主从架构实现的,因为具备木桶效应,要加得所有节点一起加,否则另一个节点无法同步写入数据时,就会造成所有节点无法写入数据。

分库分表

在这里插入图片描述
上述是分库分表的一种情况,这种分库的模式被称为垂直分库,也就是根据业务属性的不同,会创建不同的数据库,然后由不同的业务连接不同的数据库,各自之间数据分开存储,节点之间数据不会同步,以这种方式来部署MySQL,即提高了数据库的整体吞吐量和并发能力,同时也不存在之前的存储容量的木桶问题。

⚠️ 不要认为分库分表是一种很完美的解决方案,实际上当你对项目做了分库分表之后,带来的问题、要解决的问题只会更多,只不过相较于分库分表带来的收益而言,解决问题的成本是值得的,所以才会使用分库分表技术。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/965226.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

OLED显示屏使用学习——(二)

四、OLED 原理图设计注意事项 4.1 SPI 接口设计 在 SPI 接口中需保证 BS0,BS1,BS2 全为 0,也不是接地;所以在接口配置电阻中 4.2 IIC 接口设计 在 iic 接口中需要将 BS1 配置为 1,BS0 为 0;所以 R1,R4 焊接,R2&am…

string类OJ练习题

目录 文章目录 前言 一、反转字符串 二、反转字符串 II 三、反转字符串中的单词 III 四、验证一个字符串是否是回文 五、字符串相加(大数加法) 六、字符串相乘(大数乘法) 七、把字符串转化为整数(atoi) 总结…

6-图像金字塔与轮廓检测

文章目录 6.图像金字塔与轮廓检测(1)图像金字塔定义(2)金字塔制作方法(3)轮廓检测方法(4)轮廓特征与近似(5)模板匹配方法6.图像金字塔与轮廓检测 (1)图像金字塔定义 高斯金字塔拉普拉斯金字塔 高斯金字塔:向下采样方法(缩小) 高斯金字塔:向上采样方法(放大)…

javaEE-6.网络原理-http

目录 什么是http? http的工作原理: 抓包工具 fiddler的使用 HTTP请求数据: 1.首行:​编辑 2.请求头(header) 3.空行: 4.正文(body) HTTP响应数据 1.首行:​编辑 2.响应头 3.空行: 4.响应正文…

网络安全-防御 第一次作业(由于防火墙只成功启动了一次未补截图)

防火墙安全策略课堂实验报告 一、拓扑 本实验拓扑包含预启动设备、DMZ区域(含OA Server和Web Server)、防火墙(FW1)、Trust区域(含办公区PC和生产区PC)等。具体IP地址及连接关系如给定拓扑图所示&#xf…

开源项目介绍-词云生成

开源词云项目是一个利用开源技术生成和展示词云的工具或框架,广泛应用于文本分析、数据可视化等领域。以下是几个与开源词云相关的项目及其特点: Stylecloud Stylecloud 是一个由 Maximilianinir 创建和维护的开源项目,旨在通过扩展 wordclou…

使用DeepSeek的技巧笔记

来源:新年逼自己一把,学会使用DeepSeek R1_哔哩哔哩_bilibili 前言 对于DeepSeek而言,我们不再需要那么多的提示词技巧,但还是要有两个注意点:你需要理解大语言模型的工作原理与局限,这能帮助你更好的知道AI可完成任务…

redis 运维指南

一、Redis 概述 Redis(Remote Dictionary Server)是一款开源的内存数据存储系统,使用 ANSI C 语言编写,支持网络通信,可基于内存进行数据存储以实现高效读写,同时也提供了持久化功能将数据保存到磁盘。它以…

Windows本地部署DeepSeek-R1大模型并使用web界面远程交互

文章目录 前言1. 安装Ollama2. 安装DeepSeek-r1模型3. 安装图形化界面3.1 Windows系统安装Docker3.2 Docker部署Open WebUI3.3 添加Deepseek模型 4. 安装内网穿透工具5. 配置固定公网地址 前言 最近爆火的国产AI大模型Deepseek详细大家都不陌生,不过除了在手机上安…

LabVIEW与PLC交互

一、写法 写命令立即读出 写命令后立即读出,在同一时间不能有多个地方写入,因此需要在整个写入后读出过程加锁 项目中会存在多个循环并行执行该VI,轮询PLC指令 在锁内耗时,就是TCP读写的实际耗时为5-8ms,在主VI六个…

【PDF多区域识别】如何批量PDF指定多个区域识别改名,基于Windows自带的UWP的文字识别实现方案

海关在对进口货物进行查验时,需要核对报关单上的各项信息。对报关单 PDF 批量指定区域识别改名后,海关工作人员可以更高效地从文件名中获取关键信息,如货物来源地、申报价值等。例如文件名 “[原产国]_[申报价值].pdf”,有助于海关快速筛选重点查验对象,提高查验效率和监管…

用python实现进度条

前言 在Python中,可以使用多种方式实现进度条。以下是几种常见的进度条格式的实现方法: 1. 使用 tqdm 库 tqdm 是一个非常流行的库,可以轻松地在循环中显示进度条。 from tqdm import tqdm import time# 示例:简单的进度条 fo…

每日一题洛谷P5721 【深基4.例6】数字直角三角形c++

#include<iostream> using namespace std; int main() {int n;cin >> n;int t 1;for (int i 0; i < n; i) {for (int j 0; j < n - i; j) {printf("%02d",t);t;}cout << endl;}return 0; }

Python----Python高级(并发编程:进程Process,多进程,进程间通信,进程同步,进程池)

一、进程Process 拥有自己独立的堆和栈&#xff0c;既不共享堆&#xff0c;也不共享栈&#xff0c;进程由操作系统调度&#xff1b;进程切换需要的资源很最大&#xff0c;效率低。 对于操作系统来说&#xff0c;一个任务就是一个进程&#xff08;Process&#xff09;&#xff…

Python 梯度下降法(六):Nadam Optimize

文章目录 Python 梯度下降法&#xff08;六&#xff09;&#xff1a;Nadam Optimize一、数学原理1.1 介绍1.2 符号定义1.3 实现流程 二、代码实现2.1 函数代码2.2 总代码 三、优缺点3.1 优点3.2 缺点 四、相关链接 Python 梯度下降法&#xff08;六&#xff09;&#xff1a;Nad…

《Kettle保姆级教学-界面介绍》

目录 一、Kettle介绍二、界面介绍1.界面构成2、菜单栏详细介绍2.1 【文件F】2.2 【编辑】2.3 【视图】2.4 【执行】2.5 【工具】2.6 【帮助】 3、转换界面介绍4、作业界面介绍5、执行结果 一、Kettle介绍 Kettle 是一个开源的 ETL&#xff08;Extract, Transform, Load&#x…

Spring Boot篇

为什么要用Spring Boot Spring Boot 优点非常多&#xff0c;如&#xff1a; 独立运行 Spring Boot 而且内嵌了各种 servlet 容器&#xff0c;Tomcat、Jetty 等&#xff0c;现在不再需要打成 war 包部署到 容器 中&#xff0c;Spring Boot 只要打成一个可执行的 jar 包就能独…

C# 中记录(Record)详解

从C#9.0开始&#xff0c;我们有了一个有趣的语法糖&#xff1a;记录(record)   为什么提供记录&#xff1f; 开发过程中&#xff0c;我们往往会创建一些简单的实体&#xff0c;它们仅仅拥有一些简单的属性&#xff0c;可能还有几个简单的方法&#xff0c;比如DTO等等&#xf…

Page Assist - 本地Deepseek模型 Web UI 的安装和使用

Page Assist Page Assist是一个开源的Chrome扩展程序&#xff0c;为本地AI模型提供一个直观的交互界面。通过它可以在任何网页上打开侧边栏或Web UI&#xff0c;与自己的AI模型进行对话&#xff0c;获取智能辅助。这种设计不仅方便了用户随时调用AI的能力&#xff0c;还保护了…

UE求职Demo开发日志#21 背包-仓库-装备栏移动物品

1 创建一个枚举记录来源位置 UENUM(BlueprintType) enum class EMyItemLocation : uint8 {None0,Bag UMETA(DisplayName "Bag"),Armed UMETA(DisplayName "Armed"),WareHouse UMETA(DisplayName "WareHouse"), }; 2 创建一个BagPad和WarePa…