java学习八股之Mysql-事务-锁-索引-sql优化-隔离级别

2023-08-10 16:01:34 浏览数 (1)

欢迎评论区纠错和建议,祝大家伸手就是大厂offer~

三、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.MySQL有哪些索引

主键索引:一张表只能有一个主键索引,不能有空值和重复值

唯一索引:唯一索引不能有相同值,但允许为空

普通索引:允许出现重复值

组合索引:对多个字段建立一个联合索引,减少索引开销,遵循最左匹配原则

全文索引:myisam引擎支持,通过建立倒排序索引提升检索效率,广泛用于搜索索引

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有哪些锁

基于粒度:

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

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

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

基于属性:

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

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

0 人点赞