MySQL查询
MySQL8查询缓存已经废弃
为什么MySQL的索引使用的是B+树?
- 索引是一个类似于字典的工具,其结构肯定是key-value形式,有key才能查询到value
- Hash、二叉树、平衡树都可以实现key-value,但像Hash会出现碰撞,数据量大碰撞再多,那么想查找一定范围的值只能全部遍历;而二叉树、排序树之类的数据量一大了起来,那么树的层数一定会多,而层多了对I/O的请求也就多了起来,性能就下来了。
注:一般情况下,使用B+树时,在处理千万条的数据,树的深度差不多是3-4层
聚簇索引和非聚簇索引
数据和索引存储到一起的叫聚簇索引,否则就是非聚簇索引。主键是聚簇索引,那么其他索引的叶子节点的数据存入的是主键ID
回表与索引覆盖
MVCC 多版本并发控制
隔离级别
隔离级别 |
---|
未提交读(Read uncommitted) |
已提交读(Read committed) |
可重复读(Repeatable read) 默认 |
可串行化(Serializable ) |
当前读和快照读
当前读:读取的是最新版本,并且对读取的记录加锁,阻塞其他事务同时改动相同记录,避免出现安全问题。
SQL中属于的当前读:
- select…lock in share mode (共享读锁)
- select…for update 排他锁
- update , delete , insert
快照读:读取的是最后一个历史版本
一个记录中隐藏的字段
- DB_TRX_ID: 6字节DB_TRX_ID字段,表示最后更新的事务id(update,delete,insert)。
- DB_ROLL_PTR:7字节回滚指针,指向前一个版本的undolog记录,组成undo链表。
- DB_ROW_ID: 6字节的DB_ROW_ID字段,隐藏主键。
readview
事务进行快照读时产生的读视图
readView 结构:
-
trx_list: 一个列表, 存储当前系统活跃的事务id (重点)
-
up_limit_id: 存trx_list的最小值
-
low_limit_id: 系统分配给下一个事务的id
RR级别下,事务中的第一个SELECT请求才开始创建read view;
RC级别下,事务中每次SELECT请求都会重新创建read view;
可见性算法
- 如果
DB_TRX_ID< up_limit_id
,说明“最新修改该行的事务”在“当前事务”创建快照之前就提交了,所以该记录行的值对当前事务是可见的。 - 如果
DB_TRX_ID>= low_limit_id
,说明“最新修改该行的事务”在“当前事务”创建快照之后才修改该行,所以该记录行的值对当前事务不可见。 - 如果DB_TRX_ID在read view的活跃的事务中,则代表这个事务还是活跃的,没有commit,所以最新的修改对当前事务是不可见的,反之,修改的对当前事务是可见的。