Mysql-事务-锁-索引-sql优化-隔离级别

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: Mysql-事务-锁-索引-sql优化-隔离级别

三、Mysql

1.事务的特征ACID和保证

原子性:事务内的操作统一成功或者失败

由undolog日志保证,他记录了需要回滚的日志信息,回滚时撤销已执行的sql

一致性:事务执行前后数据总量不变

由其他三大特性共同保证,是事务的目的

隔离性:事务之间互不影响

由MVCC保证

持久性:事务一旦提交就不可逆

由redolog日志和内存保证,mysql修改数据时内存和redolog会记录操作,宕机时可恢复

3.事务的隔离级别

高并发情况下,并发事务会发生脏读、不可重复读、幻读问题,这时需要用隔离界别来控制

读未提交:允许事务读取另一个事务未提交的数据,有脏读问题(未提交的数据回滚导致读取的数据无效)

读已提交:只允许事务读取到其他事务已提交的数据,有不可重复读问题(多次读取结果不一致)

可重复读:多次读取结果一致,有幻读问题(b事务对a事务操作的数据做了修改,并且b事务先提交,a感觉自己的操作不起作用,十分魔幻)

可串行化:所有事务依次执行,没有并发问题

Inno DB 默认隔离级别为可重复读级别,分为快照度和当前读,并且通过间隙锁解决了幻读问题

5.MVCC原理

MVCC多版本并发控制,为每次事务生成一个新版本数据,每个事务都有自己的版本,从而不加锁拒绝读写冲突,这种读叫做快照读,只在读已提交和可重复读中生效,实现原理由四个东西保证,分别是

undolog日志:记录了数据历史版本

redaView:事务进行快照读生成的视图,记录了当前系统中活跃的事务id,控制哪个历史版本对当前事务可见

隐藏字段DB_TRC_ID:最近修改记录的事务id

隐藏字段DB_Roll_PTR:回滚指针,配合undolog指向数据的上一个版本

6. 索引分类与数据结构

  • 数据结构分类:B+树,Hash索引,Full-text索引
  • 物理存储分类:聚集索引、非聚集索引
  • 字段特性分类:主键索引(PRIMARY KEY)、唯一索引(UNIQUE)、普通索引(INDEX)、全文索引(FULLTEXT)
  • 字段个数分类:单列索引、联合索引(也叫复合索引、组合索引)

如果一个表没有主键索引依旧会创建B+树

在InnoDB中,会为每一张表创建一个主键索引,如果没有明确的主键索引,会使用一个隐藏(ROW ID)的、自动生成的主键来创建索引。建议每个表都添加主键索引。

HASH索引

在InnoDB中不支持mysql,即使选择了hash索引,但是使用的依旧是B+,InnoDB只支持自适应的HASH索引,手动选择无效。

memory支持hash索引,存在hash冲突,使用链表解决

聚簇索引和非聚簇索引

聚集索引将索引和数据放在一起,非聚集索引分离开存储,所以需要二次查找。

在MySQL中二级索引使用非聚集索引 ,除了主键索引都是二级索引。二级索引叶子节点存储主键id,根据id再次通过主键索引查找,这叫回表

覆盖索引

查询的字段都在索引列中叫覆盖索引。

索引下推

二级索引中的优化手段,在范围查询中减少回表次数,没有索引下推的时候,一个范围查询使用二级索引,第一次查询了一个范围的主键,假设查询到10条数据,那么需要回表十次,如果使用索引下推,那么只需要回表一次,就可以拿到十条数据。

单列索引

索引只有一个字段,即使是中文,构成的B+树也是有序的

联合索引

构成索引的是多个字段。如何保证数据有序?

假设有三个字段 name、age、id

那就按照name、age、id的先后顺序排序,最后这些字段都在B+树的叶子节点上。

最左前缀原则

当我创建n个字段的联合索引时,若想使用索引查询,查询条件必须使用第一个字段,因为联合索引是按照字段顺序排序的,没有第一个字段就是乱序。

创建A B C的联合索引,AB、AC、ABC都是可以走联合索引的,但是BC不可以

切记合理使用单列索引和联合索引,不可盲目添加索引

索引优缺点

优点:提高检索效率;减低排序成本,默认asc。

缺点:创建和维护索引需要时间;占用物理空间;降低表的增删改效率。

7.聚簇索引和非聚簇索引的区别

聚簇索引:聚簇索引的叶子节点存放的是主键值和数据行;辅助索引(在聚簇索引上创建的其它索引)的叶子节点存放的是主键值或指向数据行的指针。

优点:根据索引可以直接获取值,所以他获取数据更快;对于主键的排序查找和范围查找效率更高;

缺点:如果主键值很大的话,辅助索引也会变得很大;如果用uuid作为主键,数据存储会很稀疏;修改主键或乱序插入会让数据行移动导致页分裂;所以一般我们定义主键时尽量让主键值小,并且定义为自增和不可修改。

非聚簇索引(辅助索引):叶子节点存放的是数据行地址,先根据索引找到数据地址,再根据地址去找数据,需要回表二次查找

他们都是b+数结构

8.MySQL如何做sql优化

可以查看执行计划分析数据的扫描类型、索引是否生效,常见的慢优化有:

  1. 减少select的数据列,使用覆盖索引
  2. order by使用索引排序,否则的话会回表查询
  3. group by同样使用索引,避免使用临时表
  4. 分页查询如果limit后面的数字很大,使用子查询查出主键,再limit后主键就能走覆盖索引
  5. 使用复杂查询的时候,使用关联查询来代替子查询,最好使用内连接
  6. 使用count函数的时候count(*)效率最高,count(字段)不会统计null
  7. update的时候,where要加索引,否则会从行锁升级到表锁
  8. 表中数据是否太大,是不是要分库分表

9.为什么要用内连接而不用外连接?

用外连接的话连接顺序是固定死的,比如left join,他必须先对左表进行全表扫描,然后一条条到右表去匹配;而内连接的话mysql会自己根据查询优化器去判断用哪个表做驱动。

子查询的话同样也会对驱动表进行全表扫描,所以尽量用小表做驱动表。

10.MySQL整个查询的过程

(1)客户端向 MySQL 服务器发送一条查询请求

(2)服务器首先检查查询缓存,如果命中缓存,则返回存储在缓存中的结果。否则进入下一阶段

(3)服务器进行 SQL 解析、预处理、再由优化器生成对应的执行计划

(4)MySQL 根据执行计划,调用存储引擎的 API 来执行查询

(5)将结果返回给客户端,同时缓存查询结果

注意:只有在8.0之前才有查询缓存,8.0之后查询缓存被去掉了

11.B和B+数的区别,为什么使用B+数

二叉树:索引字段有序,极端情况会变成链表形式

AVL数:树的高度不可控

B数:控制了树的高度,但是索引值和data都分布在每个具体的节点当中,若要进行范围查询,要进行多次回溯,IO开销大

B+树:非叶子节点只存储索引值,叶子节点再存储索引+具体数据,从小到大用链表连接在一起,范围查询可直接遍历不需要回溯

12.MySQL有哪些锁

基于粒度:

表级锁:对整张表加锁,粒度大并发小

行级锁:对行加锁,粒度小并发大

间隙锁:间隙锁,锁住表的一个区间,间隙锁之间不会冲突只在可重复读下才生效,解决了幻读

基于属性:

共享锁:又称读锁,一个事务为表加了读锁,其它事务只能加读锁,不能加写锁

排他锁:又称写锁,一个事务加写锁之后,其他事务不能再加任何锁,避免脏读

13. redo log 重做日志

保证事务的持久性,Innodb才有的日志

直接刷入磁盘有两个问题:Innodb以页为单位,每个事务可能只修改几个字节,浪费资源;一个事务可能涉及多个页,物理上不连续,随机IO性能太差

redo log写入机制

redo log包括两个部分:一个是内存中的日志缓冲( redo log buffer ),另一个是磁盘上的日志文件( redo logfile)。

先写入buffer中,通过innodb_flush_log_at_trx_commit字段的规则写入磁盘

0 每次事务提交都只把redo log写入buffer

1 每次提交持久化到磁盘

2 每次提交只写入到page cache

14. bin log 归档日志

记录数据的写入性操作,二进制的形势保存到磁盘,

使用场景

主从复制:通过bin log实现数据一致性

数据恢复:使用mysql binlog恢复数据

bin log输盘时机

sync_binlog 参数控制刷盘时机,范围是0-N

0 系统判断何时刷入

1 每次commit都写入磁盘

2 每N个事务写入磁盘

15. undo log日志

保证事务原子性

记录数据的逻辑变化,例如insert对应一条delete,发生错误的时候可以回滚,是实现MVCC的关键

16. 索引失效的场景

like左%、or关键字、字段转换、字段计算、使用函数、字段比较、order by

17. 两阶段提交

首先再事务中,redolog会一边执行一边写入,binlog只有再事务提交之后才会写入,导致两份日志逻辑不一致,这个时候有其他写操作就会抛出异常。为了解决这个问题,InnoDB使用两阶段提交。

在写入redolog的时候也就是prepare阶段,可以写入redolog日志,当事务提交之后再写入binlog,写完之后redolog设置为commit阶段,这个时候其他线程来写,抛出异常也不影响。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
5天前
|
SQL 关系型数据库 MySQL
深入解析MySQL的EXPLAIN:指标详解与索引优化
MySQL 中的 `EXPLAIN` 语句用于分析和优化 SQL 查询,帮助你了解查询优化器的执行计划。本文详细介绍了 `EXPLAIN` 输出的各项指标,如 `id`、`select_type`、`table`、`type`、`key` 等,并提供了如何利用这些指标优化索引结构和 SQL 语句的具体方法。通过实战案例,展示了如何通过创建合适索引和调整查询语句来提升查询性能。
42 9
|
2天前
|
存储 Oracle 关系型数据库
索引在手,查询无忧:MySQL索引简介
MySQL 是一款广泛使用的关系型数据库管理系统,在2024年5月的DB-Engines排名中得分1084,仅次于Oracle。本文介绍MySQL索引的工作原理和类型,包括B+Tree、Hash、Full-text索引,以及主键、唯一、普通索引等,帮助开发者优化查询性能。索引类似于图书馆的分类系统,能快速定位数据行,极大提高检索效率。
24 8
|
3天前
|
SQL 关系型数据库 MySQL
MySQL进阶突击系列(04)事务隔离级别、AICD、CAP、BASE原则一直搞不懂? | 看这篇就够了
本文详细介绍了数据库事务的四大特性(AICD原则),包括原子性、隔离性、一致性和持久性,并深入探讨了事务并发问题与隔离级别。同时,文章还讲解了分布式系统中的CAP理论及其不可能三角关系,以及BASE原则在分布式系统设计中的应用。通过具体案例和图解,帮助读者理解事务处理的核心概念和最佳实践,为应对相关技术面试提供了全面的知识准备。
|
8天前
|
缓存 关系型数据库 MySQL
MySQL 索引优化以及慢查询优化
通过本文的介绍,希望您能够深入理解MySQL索引优化和慢查询优化的方法,并在实际应用中灵活运用这些技术,提升数据库的整体性能。
17 7
|
7天前
|
缓存 关系型数据库 MySQL
MySQL 索引优化与慢查询优化:原理与实践
通过本文的介绍,希望您能够深入理解MySQL索引优化与慢查询优化的原理和实践方法,并在实际项目中灵活运用这些技术,提升数据库的整体性能。
27 5
|
SQL 存储 数据库
SQLServer 延迟事务持久性
原文:SQLServer 延迟事务持久性 SQL Server 2014新功能 -- 延迟事务持久性(Delayed Transaction Durability) SQL Server事务提交默认是完全持久性的(Full Durable),从SQL Server 2014开始,增加了新的功能延迟事务持久性,使得事务提交可设置为延时持久性的(Delayed Durable,也叫做(Lazy Commit))。
1087 0
|
3月前
|
关系型数据库 MySQL 网络安全
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
|
5月前
|
SQL 存储 监控
SQL Server的并行实施如何优化?
【7月更文挑战第23天】SQL Server的并行实施如何优化?
134 13
|
5月前
|
SQL
解锁 SQL Server 2022的时间序列数据功能
【7月更文挑战第14天】要解锁SQL Server 2022的时间序列数据功能,可使用`generate_series`函数生成整数序列,例如:`SELECT value FROM generate_series(1, 10)。此外,`date_bucket`函数能按指定间隔(如周)对日期时间值分组,这些工具结合窗口函数和其他时间日期函数,能高效处理和分析时间序列数据。更多信息请参考官方文档和技术资料。
|
5月前
|
SQL 存储 网络安全
关系数据库SQLserver 安装 SQL Server
【7月更文挑战第26天】
69 6

推荐镜像

更多
下一篇
DataWorks