思维导图
引擎篇
myisam 和 innodb的区别
- myisam不支持事务,innodb支持事务
- myisam不支持行级锁,innodb支持行级锁
- myisam不支持外键,innodb支持外键
- myisam是非聚簇索引且数据文件和索引文件分离,InnoDB是聚簇索引
- myisam用变量保存了整个表的行数,InnoDB不保存表的具体行数
索引篇
聚簇索引
- 聚簇索引包含所有字段,非聚簇索引只包含索引字段+主键字段(MyISAM引擎中是行指针)
- 聚簇索引是顺序结构与数据存储物理结构一致的一种索引
- 由于一张表只能按照一种物理顺序存放,一张表最多也只能存在一个聚簇索引
- 如果在使用非聚集索引后还需要使用其他字段的则需要通过主键回表到聚簇索引获取其他字段,这也是为什么提倡使用全覆盖索引的原因。
索引合并(index merge)
- 对多个索引分别进行条件扫描,然后将它们各自的结果进行合并(intersect/union)。
- 可以通过EXPLAIN中type列的值是否为index_merge判断是否使用了索引合并
事务篇
事务的ACID分别指的是什么?
- 原子性
- 一致性
- 隔离性
- 持久性
事务隔离级别
隔离级别 | 说明 | 存在问题 |
---|---|---|
READ UNCOMMITTED:未提交读 | 读取未提交内容,所有事务可看到其他未提交事务的结果 | 脏读、不可重复读、幻读 |
READ COMMITTED:提交读 | 一个事务只能看到已提交事务所做的改变 | 不可重复读、幻读 |
REPEATABLE READ:可重复读(MySQL默认) | 一个事务中多次读取结果相同 | 幻读 |
SERIALIZABLE:串行化 | 强制事务排序,不会互相冲突 | - |
什么是快照读和当前读
- 当前读,select lock in share mode(共享锁), select for update ; update, insert ,delete(排他锁)等操作需要获得最新的记录。
- 快照读,不加锁的select操作就是快照读。
MySQL是如何解决RR事务隔离级别下的幻读
- RR事务隔离级别的关键就在于快照读和当前读的处理
- 快照读通过MVCC(多版本并发控制)利用历史数据部分避免了幻读,要完全避免,需要调整为当前读
- 当前读引入了next-key锁使得读和插入事务串行。
什么是MVCC
- 在事务级别为RR(可重复读)和RC(读提交)时生效
- 主要有三个关键点:三个隐藏字段(滚动指针)、undo log、read view
- 隐藏字段中存有指向undo log临时数据(可以认为历史版本)的指针。
- undo log是回滚日志,每开启事务就会生成一条临时数据并以链表的方式存在日志中。
- read view一致性视图,为某一时刻事务系统的快照,结合数据可见性规则(可以简单任务版本号小于等于事务id的可见)来判断数据是否对当前事务可见
锁篇
锁模式
锁模式 | 显隐 | 对象 | 加锁方式 |
---|---|---|---|
共享锁 | 显性 | 行 | 普通select不加锁,需要加lock in share mode |
排他锁 | 显性 | 行 | 增、删、改和select ... for update |
意向共享锁 | 隐性 | 表 | 获取行共享锁前 |
意向排他锁 | 隐性 | 表 | 获取行排他锁前 |
next-key锁 | 隐性 | 区间(相当于间隙锁+行锁) | RR隔离级别下,使用范围条件并请求加锁时 |
间隙锁 | 隐性 | 间隙 | next-key锁的一部分 |
事务中锁获取/释放的时机
- 锁定,执行sql时获取锁
- 释放,事务执行commit或者rollback时释放。
索引算法篇
B树特点
- 在每个节点上的键值,以递增顺序排列
- 左子树的键值都小于右子树的键值,父节点的键值可以等同于右子节点的键值
- 指向子节点的指针数量总是存储数据节点的数量+1
- 叶子节点的高度一致
- 无论是内部节点还是叶子节点,其存储的键值数量在[t-1,2t-1]之间
B+树和B树的区别
- B树的内部节点也是数据,但B+树只是索引
- B树叶子节点是通过父节点联系起来的,但B+树叶子节点之间还用指针串联起来
B+树比较B树的优点
- 由于叶子节点间存在指针,数据的便利更快。
画出B树/B+树的插入和删除
哈希索引
- 跟HashMap原理类似,采用一定的哈希算法,把键值换算成新的哈希值,通过hash值检索到数据
- 等值查询时,速度很快
- 范围查询,不起作用
- 无法使用索引排序
- 也不存在联合索引的最左匹配原则
优化篇
explain核心思维导图
explain思维导图
explain 各个字段解析
优化步骤
- show status命令或者慢查询日志定位执行效率慢的sql
- 如果是复杂sql,判断是否能够拆成简单sql
- explain分析sql
- show profiles工具分析sql
- trace分析优化器如何选择执行计划
其他
什么是redo log?什么undo log?
- redo log重做日志,是MySQL的持久化保障机制,事务在执行过程中对数据库所做的所有修改都会记录在redo log中,在之后系统崩溃重启后可以把事务所做的任何修改都恢复出来
- undo log回滚日志,是实现原子性的关键,是mysql实现MVCC的重要部件,它记录了回滚需要的所有信息
- MySQL为了提高的性能,对于增、删、改这种操作都是在内存中完成的,并且在事务提交的时候,必须先将该事务的redo log和undo log进行持久化
sql执行的顺序
from+join -> where -> group by -> having -> select -> order by -> limit
mysql主从复制的方式
- 同步
- 异步
- 半异步,复制给一台从库后就回应用户
mysql主从复制时启动的线程
- 主库的bin-log输出线程,将主库bin-log日志发完从库
- 从库的I/O线程,接收主库的bin-log日志,写入relay-log日志
- 从库的SQL线程,读取relay-log日志执行sql
mysql的bin-log和relay-log
- bin-log的主要作用是记录数据库中表的更改,它只记录改变数据的sql
- relay-log的主要作用是记录文件复制的进度