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

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群版 2核4GB 100GB
推荐场景:
搭建个人博客
日志服务 SLS,月写入数据量 50GB 1个月
简介: 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阶段,这个时候其他线程来写,抛出异常也不影响。

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1天前
|
存储 关系型数据库 MySQL
mysql optimizer_switch : 查询优化器优化策略深入解析
mysql optimizer_switch : 查询优化器优化策略深入解析
|
1天前
|
关系型数据库 MySQL 数据库
数据迁移脚本优化过程:从 MySQL 到 Django 模型表
在大规模的数据迁移过程中,性能问题往往是开发者面临的主要挑战之一。本文将分析一个数据迁移脚本的优化过程,展示如何从 MySQL 数据库迁移数据到 Django 模型表,并探讨优化前后的性能差异。
|
2天前
|
关系型数据库 MySQL 分布式数据库
PolarDB产品使用问题之 MySQL数据库中,执行delete命令删除数据后,存储空间通常不会立即释放,该如何优化
PolarDB产品使用合集涵盖了从创建与管理、数据管理、性能优化与诊断、安全与合规到生态与集成、运维与支持等全方位的功能和服务,旨在帮助企业轻松构建高可用、高性能且易于管理的数据库环境,满足不同业务场景的需求。用户可以通过阿里云控制台、API、SDK等方式便捷地使用这些功能,实现数据库的高效运维与持续优化。
|
1天前
|
关系型数据库 MySQL 数据库
MySQL索引优化:深入理解索引合并
MySQL索引优化:深入理解索引合并
|
1天前
|
存储 关系型数据库 MySQL
技术笔记:MySQL数据库优化详解(收藏)
技术笔记:MySQL数据库优化详解(收藏)
|
1天前
|
缓存 关系型数据库 MySQL
欢迎来到MySQL优化之旅
欢迎来到MySQL优化之旅
6 0
|
2天前
|
SQL 关系型数据库 分布式数据库
PolarDB产品使用问题之如何查看SQL语句使用的是行索引还是列索引
PolarDB产品使用合集涵盖了从创建与管理、数据管理、性能优化与诊断、安全与合规到生态与集成、运维与支持等全方位的功能和服务,旨在帮助企业轻松构建高可用、高性能且易于管理的数据库环境,满足不同业务场景的需求。用户可以通过阿里云控制台、API、SDK等方式便捷地使用这些功能,实现数据库的高效运维与持续优化。
|
2天前
|
存储 关系型数据库 MySQL
深入解析MySQL 8:事务数据字典的变革
深入解析MySQL 8:事务数据字典的变革
|
2天前
|
SQL 运维 关系型数据库
|
2天前
|
存储 关系型数据库 MySQL