MYSQL-8.调优

性能优化思维

整体思维

  1. 木桶效应:系统的性能符合木桶效应(一个木桶能装多少水,取决于木桶中最短的那块木板),所以性能优化需要从多个方面去考虑,如架构优化、业务优化、前端优化、中间件调优、网关优化、JVM优化、数据库优化、代码优化、容器/硬件优化等;
  2. 优化分类
    1. 架构优化:从系统整体架构考虑,如:读写分离、集群部署、引入缓存/搜索/消息中间件、中台架构、分库分表等;
    2. 参数优化:从系统组件方面考虑,如:JVM、服务器、数据库、中间件、网关、容器等组件的参数调整;
    3. 代码优化:从代码方面考虑,如:代码中采用更优秀的算法思想/设计模式、SQL优化、对中间件的操作优化等;

单个服务层面

  1. 在程序中,业务的执行实体都是线程,所以程序的性能一般与线程挂钩;
    1. CPU、内存、磁盘等硬件资源:线程最终会由CPU进行调度(时间片轮训)执行,且在线程的执行过程也必然需要对数据进行操作(绝大部分的业务本质都是对数据的CURD)最终都是与内存、磁盘打交道;

      1. 关联:线程越多,需要的CPU调度能力也就越强,需要的内存也越大,磁盘IO速率也会要求越快,当三者之间任意一个达到了瓶颈,程序中的线程数量也会达到极限,达到极限后,系统的性能会成抛物线式下滑,从而可能导致系统整体性能下降乃至瘫痪;
        所以一般不能让CPU、内存、磁盘等资源的使用率达到95%+,最大利用率控制在80-85%左右为最佳状态。
  2. 线程工作模型:程序设计中主要存在三种线程处理模型:BIO、NIO、AIO;可以参考;
    1. BIO阻塞IO模型:BIO是最传统的一对一处理模型,也就是一个客户端请求分配一条线程处理;
    2. NIO非阻塞IO模型:NIO的最佳实践为reactor模型;
    3. AIO异步IO模型:AIO落地实现proactor模型;

架构层面

  1. 优秀且合适的架构胜过多次调优:一个使用Tomcat+MySQL部署的系统,无论如何调优都无法处理万级并发;
  2. 架构需要符合实际业务,没有完美的架构只有最合适的架构,从现有环境及实际业务出发,选用最为合适的技术体系,这才是我们应该做的事情。如:
    1. 项目业务中读写参半,单节点难以承载压力,可以考虑项目集群、双主热备值等;
    2. 项目业务中写大于读,可以考虑引入消息中间件、DB分库、项目集群等;
    3. 项目业务中读大于写,可以考虑引入缓存/搜索中间件、动静分离、读写分离等;
  3. 架构可以进一步优化,当系统原有架构遇到性能瓶颈时,可以考虑进一步做架构优化,如:设计多级分布式缓存、缓存中间件做集群、消息中间件做集群、Java程序做集群、数据库做分库分表、搜索中间件做集群等,随着引入的技术越多,系统会越庞大,需要考虑的问题也会更加棘手,但带来的性能提升也是显著的;

预防大于解决

  1. 当问题在出现时再想办法解决,这是一种下下策,防范于未然才是最佳方案
  2. 项目初期:在项目初期,我们应该对未来的流量压力、数据大小等进行预测,提前根据业务和设计出合适的架构,确保上线后可以承载业务的正常压力和增长;不要“卡点”设计,也不能过度设计造成性能过剩
  3. 项目上线后:计划赶不上变化,项目初期的预测难免会出现偏差,一套完善的监控系统,在性能瓶颈来临前设好警报线,确保能够在真正的性能瓶颈到来之前解决问题;

性能调优的核心步骤

通常而言,性能优化的步骤可分为如下几步:

  1. 发现性能瓶颈:如有监控系统,那它会主动发出警报;如若没有,那出现瓶颈时应用肯定会出问题,如:无响应、响应缓慢、频繁宕机等。
  2. 排查瓶颈原因:排查瓶颈是由于故障问题导致的,还是真的存在性能瓶颈。
  3. 定位瓶颈位置:往往一个系统都会由多个层面协同工作,然后对外提供服务,当发现性能瓶颈时,应当确定瓶颈的范围,如:网络带宽瓶颈、Java应用瓶颈、数据库瓶颈等。
  4. 解决性能瓶颈:定位到具体的瓶颈后对症下药,从结构、配置、操作等方面出发,着手解决瓶颈问题。

Mysql性能优化

一般分为五个维度

客户端与连接层优化

调整客户端DB连接池参数和DB连接层参数;

  1. 客户端的连接池大小设置可以参考PostgreSQL的计算公式:最大连接数 = (CPU核心数 x 2) + 有效磁盘数(SSD固态硬盘数量)
    1. 为什么不限制服务端连接数MySQL实例一般情况下只为单个项目提供服务,应用程序的连接数做了限制,自然也就限制了服务端的连接数;
    2. 正常来说MySQL的最大连接数应大于客户端连接池的最大连接数,存在通过终端工具远程连接MySQL等情况,如果设置一致就很有可能导致MySQL连接数爆满;
    3. 对于最佳连接数的计算,首先要把CPU核数放首位考虑,紧接着是磁盘,最后是网络带宽,因为带宽会影响SQL执行时间,综合考虑后才能计算出最合适的连接数大小
  2. 偶发高峰类业务的连接数配置:在某些时间段或者活动开始时,流量会高于平时流量,可以将常驻连接数配成CPU核数+1,同时缩短连接的存活时间,及时释放空闲的数据库连接;
  3. mysql最大连接数设置set max_connections = n;

Mysql参数优化:

  1. 设置方式:启动之后通过set global @@xxx = xxx的方式调整,但最好还是直接修改my.ini/my.conf配置文件;
  2. InnoDB缓冲区配置innodb_buffer_pool_size一般为内存的70%~80%
    1. 实例空间:当InnoDB的缓冲区空间大于1GB时,会自动划分多个实例空间,可以在多线程并发执行时,减少并发冲突,MySQL官方的建议是每个缓冲区实例须大于1GB,通过innodb_buffer_pool_instances设置;
  3. 工作线程缓冲区配置最好根据机器内存设置为一到两倍MB大小
    1. sort_buffer_size排序缓冲区大小,影响group by、order by...等排序操作。
      1. max_length_for_sort_data:如果排序字段值的最大长度小于该值,则会将所有要排序的字段值载入内存排序,但如果大于该值时,则会一批一批的加载排序字段值进内存,然后一边加载一边做排序
    2. read_buffer_size读取缓冲区大小,影响select...查询操作的性能。
    3. join_buffer_size联查缓冲区大小,影响join多表联查的性能。
  4. 调整临时表空间tmp_table_size、max_heap_table_size两个参数主要是限制临时表可用的内存空间,当创建的临时表空间占用超过tmp_table_size时,就会将其他新创建的临时表转到磁盘中创建;
    1. 参数大小:可以根据show global status like 'created_tmp%';统计信息决定Created_tmp_disk_tables / Created_tmp_tables * 100% = 120%
  5. 调整空闲线程的存活时间
    1. 查看数据库连接峰值show global status like 'Max_used_connections';
    2. 空闲连接的超时时间wait_timeout、interactive_timeout默认八小时也就是一个连接断开后,默认也会将对应的工作线程缓存八小时后再销毁,这里我们可以手动调整成30min~1h左右,可以让无用的连接能及时释放,减少资源的占用。

编码层面优化:

  1. 编写sql时需考虑sql是否走索引,可以参考索引使用;

  2. 查询时尽量按需取字段,避免使用*

    1. 当使用*时,解析器需要先去解析出当前要查询的表上*表示哪些字段,因此会额外增加解析成本;
    2. InnoDB会将查询的结果放入缓存中,查询的字段越多结果集也就越大占用的内存也会越大,所存储的其他数据也就越少,当其他SQL操作时,在内存中找不到数据,又会去触发磁盘IO,最终导致MySQL整体性能下降;
  3. 尽量将大事物拆分成小事物;

    1. 当事物较大且包含写事物时,会导致一部分数据长时间锁定,从而可能引起大量事物出现阻塞;
    2. 大事务也会导致日志写入时出现阻塞,这种情况下会强制触发刷盘机制,大事务的日志需要阻塞到有足够的空间时,才能继续写入日志到缓冲区,这也可能会引起线上出现阻塞,可通过show status like 'innodb_log_waits';查看是否有大事务由于redo_log_buffer不足,而在等待写入日志。
  4. 尽量避免深分页的情况select * from test limit 100000,10在MySQL的实际执行过程中,首先会查询出100010条数据,然后丢弃掉前面的10W条数据,将最后的10条数据返回;

    1. 解决办法:基于递增连续字段

      -- 第一页
      select * from test where 有序字段 >= 1 limit 10; 
      -- 第二页
      select * from test where 有序字段 >= 11 limit 10;
      
  5. 避免循环调用sql,新增和更新最好采用批量操作,查询可以先将所需数据查询出来建立映射关系;

多表连接查询

  1. 避免三表以上的连表查询,且要以小表驱动大表,原因是:连表查询的数据量是各表数据的笛卡尔积,会随着表数据增加累乘增加;

  2. 关联算法MySQL8.0之前的关联算法为Nest Loop Join嵌套循环连接算法,该算法会依照驱动表的结果集作为循环基础数据,然后通过该结果集中一条条数据,作为过滤条件去下一个表中查询数据,最后合并结果得到最终数据集;

    1. 优化器的选择逻辑:如果指定了连接条件,满足查询条件的小数据表作为驱动表。如果未指定连接条件,数据总行数少的表作为驱动表。

    2. 优化器不一定能够正确选择,最好在编写sql时考虑好;假设有a(1000条数据)、b(10条数据)两张表,select * from a as t1 left join b as t2 on t1.id = t2.id;会循环1000次查询数据,而select * from b as t1 left join a as t2 on t1.id = t2.id;只需要循环十次;

      // 伪逻辑
      for(数据 x : 驱动表){
          for(数据 y : 被驱动表){
              if (x == y){
                  // 如果符合连接条件,则记录到连接查询的结果集中.....
              }
          }
      }
      
  3. 哈希连接(Hash Join) Mysql8.0新增,对连表时存在等值连接条件且未命中索引的情况下的连接查询优化:

    在这里插入图片描述

    // 伪代码
    // 构建阶段:将小表的每行数据,根据哈希值放入内存哈希表中
    Map hashTable = new HashMap();
    for(数据 x : 构建表){
        hashTable.put(x);
    }
    
    // 探测阶段:遍历大表的每行数据与内存哈希表做连接匹配
    for(数据 y : 探测表){
        if (hashTable.get(y) != null){
            // 如果哈希处理后能够在内存哈希表中存在,
            // 则表示这条数据符合连接条件,则记录到连接查询的结果集中.....
        }
    }
    
    1. 分为两个阶段:
      1. 构建阶段:选择一张小表为构建表,然后基于连接字段做哈希处理,接着将生成的哈希值放入内存中构建出一张哈希表
      2. 探测阶段遍历大表的每一行数据,然后对连接字段做哈希处理,通过生成的哈希值与内存哈希表做比较,将符合条件的数据放入结果集;
    2. 相对于嵌套循环性能的提升:
      1. 对于大表只需要遍历一次,而嵌套循环需要遍历N次;
      2. 在探测阶段时,只需要先对数据做一次哈希处理,复杂度为O(1), 而循环连接为O(n);
    3. 存在的问题:
      1. 内存中的join_buffer_size的大小可能无法完全载入哈希表;解决办法:
        • 分批处理:在构建阶段将构建表的数据进行拆分,在探测阶段每次载入一部分到内存中,这样会导致遍历次数增多;
        • 磁盘+内存混合处理:将内存中放不下的数据放入磁盘,在探测阶段遍历大表判断时,从磁盘依次读入处理好的哈希值进行判断;
      2. Mysql采用的是磁盘+内存混合处理的方式;
    4. 使用限制:
      1. 仅支持内连接的多表连接查询;
      2. 必须要去等值连接查询条件;
      3. 连接字段可走索引的情况下,默认依旧会采用循环连接算法;
    5. 默认开启,可通过set optimizer_switch="hash_join=off";命令控制;
  4. 反连接(Anti Join) Mysql8.0新增,对与一些反范围查询操作的优化

    1. 优化场景:
      1. NOT IN (SELECT … FROM …)
      2. NOT EXISTS (SELECT … FROM …)
      3. IN (SELECT … FROM …) IS NOT TRUE
      4. EXISTS (SELECT … FROM …) IS NOT TRUE
      5. IN (SELECT … FROM …) IS FALSE
      6. EXISTS (SELECT … FROM …) IS FALSE

Mysql结构优化:

  1. 表结构优化:字段数量不能过多、主键最好自增、根据业务建立中间表等;
  2. 字段结构优化:在保证足够使用的范围内,选择最小数据类型;尽量避免NULL值等;
  3. 索引结构优化:参考之前的索引使用

整体架构优化:

  1. 引入缓存中间件解决读压力
    1. 优点:在设置合理的情况下,可以为Mysql分担70%以上的读压力;
    2. 缺点:系统变复杂,需要考虑缓存击穿、缓存穿透、缓存雪崩、数据一致性等问题
  2. 引入消息中间件解决写压力;
    1. 优点:利用了MQ流量削峰的能力,使请求平滑的到达数据库;
    2. 缺点:数据库数据存在一定的延时;
  3. 主从读写分离,适用于读多写少业务,提高mysql自身抗压能力;
    1. 优点:通过搭建集群,提高了mysql的抗压能力;
    2. 缺点:主节点和从节点之间存在数据不一致的情况;
  4. 双主双写热备,适用于写多读少的情况
    1. 需要考虑自增ID问题;
  5. 分库分表,规避存储容量的上限+木桶效应

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

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

相关文章

21物联1班常用网络命令

常用网络命令 ipconfig(配置)ping(测试)命令1:ping 172.16.0.12:ping ip -t3:ping ip -l 3000(注意每个之间都存在空格)4:ping ip -n count netstat(网络)命令…

初识C语言——第十六天

C语言中的语句结构类型:顺序/选择/循环 分支语句 if else switch 循环语句 while for do whlie goto语句 代码练习:找两个整数的最大公约数和最小公倍数 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h>//int main() //{ // int age 60; // if (ag…

探索智能编程新境界:我与Baidu Comate的独特体验之旅

文章目录 一、认识Baidu Comate二、VS Code安装Baidu Comate教程三、Baidu Comate功能体验功能概览具体功能1.根据注释自动生成代码2.函数注释3.行间注释4.代码解释5.生成单元测试6.代码优化7.答疑解惑 四、交互体验五、总结 一、认识Baidu Comate ✨Baidu Comate插件是一款基…

激光跟踪仪在石油化工领域高效应用

管板式换热器是一种实现物料之间热量传递的节能设备&#xff0c;在石油化工行业生产过程中扮演着重要的角色。无论是在提高生产效率&#xff0c;保证产品质量还是节约能源方面&#xff0c;都发挥着重要作用。 测量需求 管板式热交换器内部有多个管板和折流板&#xff0c;每一…

一个递推通项公式研究

递推关系为a(n) ​pa(n−1) ​ qa(n−2) ​&#xff0c;本项前一项*2前前项&#xff0c;具体如 1&#xff0c;1&#xff0c;3&#xff0c;7&#xff0c;17&#xff0c;41&#xff0c;99&#xff0c;239&#xff0c;…… 一般的递推关系可以用以下方法 得两个解&#xff1a; …

火山引擎A/B测试平台的实验管理重构与DDD实践

本次分享的主题是火山引擎数智平台VeDI旗下的A/B测试平台 DataTester 实验管理架构升级与DDD实践。这里说明的一点是&#xff0c;代码的第一目标肯定是满足产品需求&#xff0c;能够满足产品需求的代码都是好代码。而本文中对代码的好坏的评价完全是从架构的视角&#xff0c;结…

AlphaFold3: Google DeepMind的的新突破

AlphaFold 3的论文今天在Nature期刊发表啦!这可是AI在生物领域最厉害的突破的最新版本。AlphaFold-3的新招就是用扩散模型去"画出"分子的结构。它一开始先从一团模模糊糊的原子云下手,然后慢慢透过去噪把分子变得越来越清楚。 Alphafold3 我们活在一个从Llama和Sora那…

Baidu Comate智能编码助手:大学生的代码编写助手

Baidu Comate智能编码助手&#xff1a;大学生的代码编写助手 前言一、关于Baidu Comate智能编码助手1.1 Baidu Comate智能编码助手简介1.2 产品功能 二、安装使用&#xff08;本文以pycharm为例&#xff09;三、我的百度Comate之旅3.1智能推荐3.1.1 单行推荐3.1.2 多行推荐 3.2…

前端css中线性渐变(linear-gradient)的使用

前端css中线性渐变 一、前言二、关键词句三、主要内容说明&#xff08;一&#xff09;、线性渐变方向1.角度调整方向2.负值角度&#xff0c;源码13.源码1运行效果4.关键字调整方向5.to right向右线性渐变&#xff0c;源码26.源码2运行效果 &#xff08;二&#xff09;、线性渐变…

3D 打印为压铸行业的带来新动力

近年来&#xff0c;随着多家车企的积极引领&#xff0c;一体化压铸技术已逐渐成为汽车行业的一大趋势。该技术不仅简化了车身的制造流程&#xff0c;而且优化了供应链环节&#xff0c;成为汽车制造业中的一次创新&#xff0c;同时显著提升了经济效益。 压铸技术&#xff0c;简而…

即插即用 | YOLOv8热力图可视化方法详解,揭秘AI如何「看」世界!【附完整源码】

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

springboot3项目练习详细步骤(第一部分:用户业务模块)

目录 环境准备 用户模块 注册 注册接口文档 ​编辑 实现结构 Spring Validation 登录 登录的接口文档 实现登录逻辑 JWT令牌 完善登录认证 拦截器 获取用户详细信息 接口文档 Usercontroller类中编写方法接口 忽略属性返回 优化代码ThreadLocal 更新用户基本信…

STM32理论 —— μCOS-Ⅲ(新)

文章目录 1. 任务调度器1.1 抢占式调度 μCos-Ⅲ全称是Micro C OS Ⅲ&#xff0c;由Micriμm 公司发布的一个基于C 语言编写的第三代小型实时操作系统(RTOS)&#xff1b; RTOS 与裸机相比最大的优势在于多任务管理与实时性&#xff0c;它提供了多任务管理和任务间通信的功能&a…

交易复盘-20240509

仅用于记录当天的市场情况&#xff0c;用于统计交易策略的适用情况&#xff0c;以便程序回测 短线核心&#xff1a;不参与任何级别的调整&#xff0c;采用龙空龙模式 一支股票 10%的时候可以操作&#xff0c; 90%的时间适合空仓等待 百合花 (4)|[9:25]|[17717万]|1.93 时代万恒…

双层嵌线和线径的替代方案

电机只有三种嵌线方式 1.单层嵌线 2.双层嵌线 3.单双层嵌线 前面说的都是单层嵌线&#xff0c;下面介绍双层嵌线&#xff01; 双层嵌线一般线径都比较粗&#xff01; 线径只有几种规格的&#xff0c;大线径可用几根小线径替代&#xff01; 满足的原则&#xff1a;大线径A的…

RDB快照是怎么实现的?

RDB快照是怎么实现的&#xff1f; 前言快照怎么用&#xff1f;执行快照时&#xff0c;数据能被修改吗&#xff1f;RDB 和 AOF 合体 前言 虽说 Redis 是内存数据库&#xff0c;但是它为数据的持久化提供了两个技术。 分别是「 AOF 日志和 RDB 快照」。 这两种技术都会用各用一…

端口占用解决方法

1、查询端口 打开cmd命令提示符窗口&#xff0c;输入以下指令查询所有端口 netstat -ano //查询所有端口 netstat -ano|findstr 8080 //查询指定端口 2、杀死进程 taskkill /t /f /im 进程号(PID)

socket实现TCP UDP

1、socket通信建立流程 1.1、创建服务端流程 使用 socket 函数来创建 socket服务。 使用 bind 函数绑定端口。 使用 listen 函数监听端口。 使用 accept 函数接收客户端请求。 1.2、创建客户端流程 使用 socket 函数来创建 socket 服务。 使用 connect 函数连接到 socke…

在k8s中部署hadoop后的使用,包括服务端及客户端(客户端的安装及与k8s服务的对接)

&#xff08;作者&#xff1a;陈玓玏&#xff09; 在https://blog.csdn.net/weixin_39750084/article/details/136744772?spm1001.2014.3001.5502和https://blog.csdn.net/weixin_39750084/article/details/136750613?spm1001.2014.3001.5502这两篇文章中&#xff0c;说明…

景源畅信电商:抖音小店有哪些比较热门的宣传方法?

抖音小店的热门宣传方法&#xff0c;是许多商家关注的焦点。在数字化营销时代&#xff0c;有效的宣传手段不仅能提升品牌知名度&#xff0c;还能吸引潜在消费者&#xff0c;促进销售。以下是针对抖音小店热门宣传方法的详细阐述&#xff1a; 一、短视频内容营销 作为抖音的核心…