MySQL的架构和性能优化

news2024/10/7 4:36:03

一、架构

MySQL逻辑架构整体分为三层,最上层为客户端,并非MySQL独有,诸如:连接处理,授权认证,安全等功能均在这一层处理
MySQL大多数核心服务均在中间这一层,包括查询解析,分析优化,缓存,内置函数,所有的跨存储引擎功能也在这一层实现:存储过程,触发器,视图等。
最下层为存储引擎,负责MySQL中的数据存储和提取
image.png
image.png

1.MySQL查询过程

连接层(客户端/服务端通信协议)

  • MySQL客户端/服务端的通信协议通常是半双工,要么服务器向客户端发送数据,要么客户端向服务器发送数据,当客户端要查询的时候向服务端发送消息,进行TCP/IP连接或者socket连接,并且向服务端提供自己的用户名和密码,服务端提供专用连接线程,接受用户的SQL,后返回结果

SQL层

  • 接受上层传送的SQL语句
  • 进行语义检查:判断sql语句的类型
  • 权限检查
  • 对sql语句进行解析
    • 通过关键字将sql语句进行解析,并生成一颗对应的解析树。这个过程解析器主要通过语法规则来验证和校验,比如sql中是否使用了错误的关键字或者关键字的顺序是否正确等。预处理会根据M有SQL规则进一步检查解析树是否合法等
  • 进行查询优化
    • 重新定义表的关联顺序
    • 优化MIN()和MAX()函数(找出某列的最小值,如果该列有索引,只需要查找B+tree索引最左端)
    • 提前终止查询(比如:使用limit时,查找到满足数量的结果集合后立即终止查询)
    • 优化排序(老版本中先读取行指针和需要排序的字段你在内存中对其排序,然后再更具排序结果去读取数据行,新版本中采用单词传输排序,一次性读取所有的数据行,然后根据给定的列排序,对于I/O密集型应用,会提高效率)
  • 性能优化
    • 用多个小表代替一个大表,不要过度设计
    • 批量插入代替循环单挑插入
    • 合理控制缓存空间大小,一般来说其大小设置为及时找比较合适
  • 查询缓存(不建议轻易打开查询缓存)
    • 在解析一个查询语句钱,如果查询缓存时打开的,那么mysql会检查这个查询语句是否名字拆线呢缓存中的数据,如果当前查询恰好命中查询缓存,在检查一次用户权限后直接返回缓存中的结果
    • mysql将缓存放在一个引用表中,可以理解为一个类似于HashMap的数据结构
    • 任何的查询语句在开始之前都必须经过检查,即使这条SQL语句永远不会命中缓存
    • 如果查询结果可以被缓存,那么执行完成后,会将结果存入缓存,也会带来额外的系统消耗

存储引擎层(类似于linux中的文件)
负责根据SQL层的执行结果,从磁盘上拿数据,返回给客户端

2.MyISAM和InnoDB的特点

MyISAM引擎特点:

  • 不支持事务(保证数据安全ACID)
  • 表级锁定
  • 读写相互阻塞,写时不能读,读时不能写
  • 只缓存索引
  • 读取数据较快,占用资源较少
  • 不支持MVCC(多版本并发控制机制)高并发
  • 奔溃恢复性较差

使用场景:
只读(或者写较少时),表较小
InnoDB引擎特点

  • 行级锁
  • 支持事务,适合处理大量短期事务
  • 读写阻塞与事务隔离级别有关
  • 可缓存数据和索引
  • 奔溃后恢复性较好
  • 支持MVCC高并发
  • MYSQL5.5后支持全文索引,也是5.5后的默认搜索引擎

备份:备份的时候备份业务数据库和mysql数据库(因为mysql数据库中有用户及权限设置)

3.修改mysql的最大并发连接数
mysql> show variables like 'max_connections';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| max_connections | 500   |
+-----------------+-------+
1 row in set (0.00 sec)
mysql> set global max_connections =2000;
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like 'max_connections';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| max_connections | 2000  |
+-----------------+-------+
1 row in set (0.00 sec)
# 也可在配置文件中修改
[root@server ~]# vim /etc/my.cnf
4.服务器状态变量

服务器状态变量:分全局和会话两种
状态变量(只读):用于保存mysqld运行中的统计数据变量,不可更改

show global status;
show [session] status;

5.服务器变量SQL_MODE

SQL_MODE:对其设置可以完成一些约束检查的工作,可分别进行全局的设置或当前会话的设置
常见MODE:

  • NO_AUTO_CREATE_USER: 禁止GRANT创建密码为空的用户
  • NO_ZERO_DATE:在严格模式,不允许使用’0000-00-00’的时间
  • ONLY_FULL_GROUP_BY: 对于GROUP BY聚合操作,如果在SELECT中的列,没有在GROUP BY中出现,那么将认为这个SQL是不合法的
  • NO_BACKSLASH_ESCAPES: 反斜杠""作为普通字符而非转义字符
  • PIPES_AS_CONCAT: 将"||"视为连接操作符而非"或"运算符

二、索引

1.index索引介绍

索引:索引是排序的快速查找的特殊数据结构,定义作为查找条件的字段,又称为key,索引通过存储引擎实现,加快查询速度

2.索引优缺点

索引的优点是可以提高检索数据的速度,这是创建索引的最主要的原因;对于有依赖关系的子表和父表之间的;联合查询时,可以提高查询速度;使用分组和排序子句进行数据查询时,同样可以显著节省查询中分组和排序的时间。
索引的缺点是创建和维护索引需要耗费时间,耗费时间的数量随着数据量的增加而增加;索引需要占用物理空间,每一个索引要占一定的物理空间;增加、删除和修改数据时,要动态的维护索引,造成数据的维护速度降低了
优点

  • 降低服务需要扫描的数据量,减少I/O次数
  • 索引可以帮助服务器避免排序和使用临时表
  • 索引可以帮助将随机I/O转为顺序 I/O

缺点:

  • 占用额外空间
  • 影响插入速度

索引类型:

  • B+ TREE、HASH、R TREE、FULL TEXT
  • 聚簇(集)索引、非聚簇索引:数据和索引是否存储在一起
  • 主键索引、二级(辅助)索引
  • 稠密索引、稀疏索引:是否索引了每一个数据项
  • 简单索引、组合索引: 是否是多个字段的索引
  • 左前缀索引:取前面的字符做索引
  • 覆盖索引:从索引中即可取出要查询的数据,性能高
3.B+TREE

B+tree索引:按顺序储存,每一个叶子节点到根节点的举例是相同的;左前缀索引,适合查询范围类的索引;
B-TREE
image.png
B+TREE
image.png
页面搜索严禁做模糊或者全模糊,如果需要择走搜索引擎来解决

说明:索引文件具有 B-Tree 的最左前缀匹配特性,如果左边的值未确定,那么无法使用此索引

可以使用B+TREE索引的查询类型

  • 全值匹配:精确所有索引列
  • 匹配最左前缀:只使用索引的第一列
  • 匹配列前缀:只匹配一列值开头部分
  • 精确匹配某一列范围并匹配另一列
  • 只访问索引的查询

B+TREE索引的限制

  • 如不从最左列开始,则无法使用索引
  • 不能跳过索引中的列
4.索引优化
  • 独立的使用列:经历避免其参与运算,独立的列指索引列不能是表达式的而一部分,也不能是函数的参数,在where条件中,始终将索引列单独放在比较符号的一侧,尽量不在列上进行运算
  • 左前缀索引:构建指定索引字段的左侧的字符数,要通过索引选择(不重复的索引值和数据表的记录总数的比值)来评估,尽量使用短索引,如果可以,指定一个前缀长度
  • 多列索引和索引顺序:AND操作时更适合使用多列索引,而非为每个列创建单独的索引;
    • 当出现多个索引做相交操作时(多个AND条件),通常来说一个包含所有相关列的索引要优于多个独立索引
    • 当出现多个索引做联合操作时(多个OR条件),对结果集的合并、排序等操作需要耗费大量的CPU和内存资源,特别是当其中的某些索引的选择性不高,需要返回大量合并数据时,查询成本更高
  • 选择合适的索引列顺序:无排序和分组时。将选择性最高放左侧
  • 只要列中含有NULL值,就最好不要在此列设置索引,复合索引如果有null值,此列在使用时也不会使用索引
  • 对于经常在where子句使用的列,最好设置索引
  • 对于有多个列where或者order by子句,应该建立复合索引
  • 对于like语句,以%或者_开头的不会使用索引,以%结尾会使用索引
  • 尽量不要使用not in 和<>操作,虽然可能使用索引,但性能不高
  • 不要使用RLIK正则表达式会导致索引失效
  • 查询时,能不用就不用,尽量写全字段名,比如select id,name,age from students;
  • 大部分情况连接效率远大于子查询
  • 在有大量记录的表分页时使用limit
  • 对于经常使用的查询,可以开启查询缓存
  • 多使用explain和profile分析查询语句
  • 查看慢日志,找出执行时间长的sql语句优化

三、并发控制

1.锁机制

类型:

  - 读锁:共享锁,也成为S锁,只读不可写(包括当前事务),多个读互不阻塞
  - 写锁:独占锁,排它锁,也成为X锁,写锁会阻塞其他事务(不包括当前事务)的的读和写
  - S锁和S锁是兼容的,X锁和其他锁都不兼容
     - 例:事务 T1 获取了一个行 r1 的 S 锁,另外事务 T2 可以立即获得行 r1 的 S 锁,此时 T1 和 T2 共同获得行 r1 的 S 锁,此种情况称为锁兼容,但是另外一个事务 T2 此时如果想获得行 r1 的 X 锁,则必须等待 T1 对行 r1 锁的释放,此种情况也称为锁冲突

锁粒度:

  - 表级锁:MyISAM
  - 行级锁:InnoDB

实现

  - 存储引擎:自行实现其锁策略和锁粒度
  - 服务器级:实现了锁、表级锁、用户可显示请求

分类:

  - 隐式锁:由于存储引擎自动施加锁
  - 显式锁:用户手动请求

锁策略:在锁粒度以及数据安全性寻求的平衡机制

四、事务

简介:事务Transactios:一组原子性的sql语句,或一个独立工作单元
事务日志:记录事务信息,实现undo,redo故障恢复功能

1.ACID特性:
  • A:automictiy原子性:整个事务中的所有操作要么全部成功执行,要么全部失败后回滚
  • C:consistency一致性:数据库总是从一个状态转换为另一个一致性状态,类似于能量守恒定律
  • I:isolation隔离性:一个事务所作出的操作是在提交之前,是不能为其他事务所见;隔离有多种隔离级别,实现并发(事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。)
  • D:Durability持久性:持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,所做的修改永久保存于数据库中,接下来即使数据库发生故障也不应该对其有任何影响,

begin
说明:在5.5 以上的版本,不需要手工begin,只要你执行的是一个DML,会自动在前面加一个begin命令。
commit:提交事务
完成一个事务,一旦事务提交成功 ,就说明具备ACID特性了。
rollback :回滚事务
将内存中,已执行过的操作,回滚回去

注意:只有事务型存储引擎中的DML语句方能支持此类操作
自动提交:
set autocommit={1|0} 默认未1,未0时设为非自动提交,为0可以提高数据库性能
死锁:
两个或多个事务在同一资源相互占用,并请求锁定对方占用的资源的状态
开始事务流程:

1、检查autocommit是否为关闭状态
select @@autocommit;
或者:
show variables like 'autocommit';

2、开启事务,并结束事务
begin
delete from student where name='alexsb';
update student set name='alexsb' where name='alex';
rollback;

begin
delete from student where name='alexsb';
update student set name='alexsb' where name='alex';
commit;

对于使用 InnoDB 存储引擎的表来说,它的聚簇索引记录中都包含 3 个隐藏列

  • db_row_id:隐藏的行 ID。在没有自定义主键也没有 Unique 键的情况下,会使用该隐藏列作为主键。
  • db_trx_id:操作这个数据的事务 ID,也就是最后一个对该数据进行插入或更新的事务 ID。
  • dbroll_ptr:回滚指针,也就是指向这个记录的 Undo Log 信息。Undo Log 中存储了回滚需要的数据
2.事务的隔离级别

多个线程开启各自事务操作数据库中数据时,数据库系统要负责隔离操作,以保证各个线程在获取数据时的准确性。
如果不考虑隔离性,可能会引发如下问题:

  • 幻读 : 是指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致。
    • 事务A 按照一定条件进行数据读取, 期间事务B 插入了相同搜索条件的新数据,事务A再次按照原先条件进行读取时,发现了事务B 新插入的数据 称为幻读。
  • 不可重复读取 :是指在数据库访问中,一个事务范围内两个相同的查询却返回了不同数据。
    • 在一个事务内,多次读同一个数据。在这个事务还没有结束时,另一个事务也访问该同一数据并修改数据。那么,在第一个事务的两次读数据之间。由于另一个事务的修改,那么第一个事务两次读到的数据可能不一样,这样就发生了在一个事务内两次读到的数据是不一样的,因此称为不可重复读,即原始读取不可重复。
  • 脏读:指一个事务读取了另外一个事务未提交的数据
# 这是非常危险的,假设A向B转帐100元,对应sql语句如下所示
1. update account set money=money+100 where name=‘b’;    
2. update account set money=money-100 where name=‘a’;
隔离级别脏读不可重复读幻读加读锁
读未提交可以出现可以出现可以出现
读提交不允许出现可以出现可以出现
可重复读不允许出现不允许出现可以出现
序列化不允许出现不允许出现不允许出现

数据库共定义了四种隔离级别:

  • Serializable:可避免脏读、不可重复读、虚读情况的发生。(串行化)
  • Repeatable read:可避免脏读、不可重复读情况的发生。(可重复读)
  • Read committed:可避免脏读情况发生(读已提交)。可读取到提交数据,但未提交数据不可读,产生不可重复读,即可读取到多个提交数据,导致每次
    读取数据不一致
  • Read uncommitted:最低级别,以上情况均无法保证。(读未提交)

MVCC和事务的隔离级别:
MVCC(多版本并发控制机制)只在READ COMMITTED和REPEATABLE READ两个隔离级别下工作。其
他两个隔离级别都和MVCC不兼容,因为READ UNCOMMITTED总是读取最新的数据行,而不是符合当前
事务版本的数据行。而SERIALIZABLE则会对所有读取的行都加锁

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Mysql】数据库第三讲(表的约束、基本查询语句)

表的约束和基本查询 1.表的约束1.1 空属性1.2默认值1.3列描述1.4 zerofill1.5主键1.6 自增长1.7 唯一键1.8外键 1.表的约束 真正约束字段的是数据类型&#xff0c;但是数据类型约束很单一&#xff0c; 需要有一些额外的约束&#xff0c; 更好的保证数据的合法性&#xff0c;从…

【Flowable】FlowableUI使用以及在IDEA使用flowable插件(二)

前言 之前有需要使用到Flowable&#xff0c;鉴于网上的资料不是很多也不是很全也是捣鼓了半天&#xff0c;因此争取能在这里简单分享一下经验&#xff0c;帮助有需要的朋友&#xff0c;也非常欢迎大家指出不足的地方。 一、部署FlowableUI 1.准备war包 在这里提供了&#xf…

Java之Hashset的原理及解析

4.数据结构 4.1二叉树【理解】 二叉树的特点 二叉树中,任意一个节点的度要小于等于2 节点: 在树结构中,每一个元素称之为节点 度: 每一个节点的子节点数量称之为度 二叉树结构图 4.2二叉查找树【理解】 二叉查找树的特点 二叉查找树,又称二叉排序树或者二叉搜索树 每一…

【算法专题突破】双指针 - 最大连续1的个数 III(11)

目录 1. 题目解析 2. 算法原理 3. 代码编写 写在最后&#xff1a; 1. 题目解析 题目链接&#xff1a;1004. 最大连续1的个数 III - 力扣&#xff08;Leetcode&#xff09; 这道题不难理解&#xff0c;其实就是求出最长的连续是1的子数组&#xff0c; 但是&#xff0c;他支…

[学习笔记]PageRank算法

参考资料&#xff1a;改变世界的谷歌PageRank算法 pagerank算法用于计算节点重要度 思想 如果网页被更多的入度(被引用)&#xff0c;则网页更重要。 被重要网站引用比被普通网站引用更加凸显重要性。 所以考虑一个网站是否重要&#xff0c;需要看引用它的网站是否重要&#…

Mysql binlog的三种模式statement,row,mixed详解,以及无主键造成复制延时的测试

2.1 Statement 模式的概念 Statement 是基于语句的复制模式。 Statement 模式将数据库中执行的修改操作记录为 SQL 语句&#xff0c;再从数据库上执行相同的 SQL 语句来实现数据同步。 2.2 Statement 模式的优点 Statement 模式的优点是简单明了&#xff0c;易于理解和实现。…

工作不好找,普通打工人如何破局

大家好&#xff0c;我是苍何&#xff0c;我的一位阿里朋友被裁后&#xff0c;找工作找了一个月都没结果&#xff0c;很多到最后一面被pass了&#xff0c;不由得做一下感慨&#xff0c;即使是大厂背景又如何&#xff0c;面对经济环境和大环境市场&#xff0c;每个人都不容易。 …

关于一个left join的易错点

很多人在学习mysql的时候应该都出现过很多问题&#xff0c;特别是连接方面的问题应该最多&#xff0c;希望这篇文章帮助到正在找bug的你 Java报错数据返回数量出现错误 遇到这种问题一定要看日志 很明显通过left join查询除了两条数据并且为空 马上思考错误的原因&#xff0c;…

【playwright】访问不同链接方法

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 访问不同页面方法方法比较 browser.new_page() page context.new_page() 1. 访问不同url 1.1 方法一 browser.new_page() 打开多个浏览器&#xff0…

JS如何判断一个变量是否为数组类型?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 使用 Array.isArray() 方法⭐ 使用 instanceof 操作符⭐ 使用 Object.prototype.toString.call() 方法⭐ 使用 Array.from() 方法⭐ 使用 Array.prototype.isArray 属性&#xff08;不推荐&#xff09;⭐ 写在最后 ⭐ 专栏简介 前端入门之…

人机融合的熵增定律

在信息论中&#xff0c;熵增定律是指在信息传输或处理过程中&#xff0c;总的熵&#xff08;即不确定性或信息的度量&#xff09;通常会增加。然而&#xff0c;对于人机融合的情况&#xff0c;熵增定律并不是一个普适的定律&#xff0c;而是取决于具体情境和应用。 当人与机器进…

uniapp-小程序登录授权框

微信官方文档 不弹出授权框原因 因为版本问题&#xff0c;目前的最新的版本是不支持 wx.getUserInfo 去主动弹出授权框 只能引导用户去点击 butten 去授权 解决方法 我的思路是参考了其他的微信微信小程序, 就是跳转到我的页面的时候 在钩子函数内去触发一个封装的模态框,状…

STM32-HAL库07-软件SPI驱动0.96寸OLED

STM32-HAL库07-软件SPI驱动0.96寸OLED 一、所用材料&#xff1a; STM32VGT6自制控制板 STM32CUBEMX&#xff08;HAL库软件&#xff09; MDK5 二、所学内容&#xff1a; 通过HAL库配置四个GPIO输出口&#xff0c;对其进行软件模拟SPI发送规则&#xff0c;进而驱动OLED进行数…

VisualStudio Code 支持C++11插件配置

问题 Visual Studio Code中的插件: Code Runner 支持运行C、C、Java、JS、PHP、Python等多种语言。 但是它不支持C11特性的一些使用&#xff0c;比如类似错误&#xff1a; binarySearch.cpp:26:17: error: non-aggregate type ‘vector’ cannot be initialized with an ini…

C++(day4)

思维导图 封装Mystring #include <iostream> #include<cstring>using namespace std;class Mystring{ public://无参构造函数Mystring():size(10){strnew char[size];strcpy(str,"");cout<<"无参构造函数"<<endl;}//有参构造函数…

前端内存泄漏和溢出的情况以及解决办法

写在前面&#xff1a; 在平时写代码时&#xff0c;内存泄漏的情况会时有发生&#xff0c;虽然js有内存回收机制&#xff0c;但在平时编程中还是需要注意避免内存泄漏的情况&#xff1b;前几天做移动端时遇到一个内存泄漏造成移动端页面卡顿的问题&#xff0c;所以想总结下前端…

GO语言网络编程(并发编程)Channel

GO语言网络编程&#xff08;并发编程&#xff09;Channel 1、Channel 1.1.1 Channel 单纯地将函数并发执行是没有意义的。函数与函数间需要交换数据才能体现并发执行函数的意义。 虽然可以使用共享内存进行数据交换&#xff0c;但是共享内存在不同的goroutine中容易发生竞态…

Linux Debian12使用git将本地项目打标签、创建分支和分支合并到master再上传到码云(gitee)远程仓库

一、git创建分支并克隆指定分支到本地 gitee官网&#xff1a;https://gitee.com/ 登录上gitee账号,我这用test仓库作测试。新建分支名称为develop&#xff0c;分支起点选择master&#xff0c;创建即可&#xff0c;如下图所示&#xff1a; 使用git管理代码版本时&#xff0…

SpringBoot 中的事务管理讲解

Spring Boot 中的事务管理 在实际的开发中&#xff0c;事务是非常重要的一个概念。在 Spring Boot 中&#xff0c;我们可以使用事务管理器来管理事务。事务管理器可以确保一系列操作要么全部成功&#xff0c;要么全部失败&#xff0c;从而保证数据的一致性和完整性。在本文中&…

音频驱动嘴型的视频数字人虚拟主播工具motionface replay使用教程

音频驱动嘴型的视频数字人虚拟主播工具motionface replay使用教程 1&#xff1a;系统要求 软件运行支持32位/64位window 10/11系统&#xff0c;内存最低要求> 8Gb.无其他硬性要求。 1&#xff1a;下载安装 打开百度网盘链接下载&#xff1a; 链接&#xff1a;百度网盘 请输入…