【MySQL是怎么运行的】0、名词解释
- 聚簇索引:聚簇=索引和数据在一起,又名主键索引,是主键id构建的一颗B+树,非叶节点是主键id,叶子节点是真实数据。其他索引统称二级索引,也称为非聚簇索引。
- 覆盖索引:查找的数据就在索引树上,不需要回表。
user表(id, name, age, phone),100行初始数据,有主键索引,name和age构建的联合索引
select id, name, age from user where id=?; √ 查找的id, name, age都在主键索引上
select name, age from user where name=? and age=?; √ 查找的name, age都在主键索引上
select * from user where name=? and age=?; x,需要的phone不在联合索引,需要回表
- 回表:从二级索引查询回到主键索引中
select * from user where name=? and age=?;
1- 获取name和age的索引树
2- 从二级索引叶子节点找到具体的id
3- 获取主键索引(回表,即拿到初始所有数据)
4- 从主键索引叶子节点找到具体的数据返回
- 全表扫描:一行行记录查询,全部回表,少一行都不行
select * from user where id between 1 and 99; x, 没有扫描第100行
- 索引下推ICP:将服务层非索引的筛选下推到存储引擎层,主要适用于联合索引
select * from user where name=? and age=?
1- 服务端向db发起请求,db连接层建立连接
2- db服务层经过缓存查,解析器解析,优化器优化后生成执行计划
3- 引擎层查磁盘获取到name和age索引树,通过name筛选出一批数据,获取id
4- 从磁盘获取主键索引,通过id进行筛选。
5- sql5.6之前将筛选后的数据返回给服务层,服务层通过phone筛选后返回服务端,5.6之后引擎层直接处理,将处理好的数据返回给服务层,减少了无效数据的传输
6- 如果是联合索引,比如abc联合索引,a=xx and b like %lucas。以前没有icp,会先筛选出a然后服务层筛选b,有了icp后,会在联合索引的b+树种筛选a,引擎层直接筛选b,不需要回表
-
事务的ACID特性
A-原子性:事务内的多个sql同时成功,同时失败,靠undo日志保证
C-一致性:事务执行前后,数据从一个合法状态转为另一个合法状态,靠业务保证
I-隔离性:事务之间相互隔离,靠MVCC和锁保证
D-持久性:持久化到磁盘,靠redo日志保证 -
数据并发问题
脏写:修改其他事物未提交的数据(a将1修改为2,b将2修改为3,a提交,预期是2,但是结果是3,a写的是错的)
脏读:读取其他事务未提交的数据(a将1修改为2,b读发现结果是2,但是a回滚了,b读的是错的)
不可重复读:读取到的数据有变化(a读取发现是1,b将1修改为2,a在同个事务内再次读取,发现是2了)
幻读:行数有变化(a读取发现2行,b新增了1行,a在同个事务内再次读取,发现是3行了) -
事务隔离级别
读未提交:可以读取其他事务未提交的结果,仅解决脏写(写时加了s锁)
读已提交:只能读取其他事务提交的结果,解决脏写和脏读
可重复读(InnoDB默认):同个事务内,读取结果不变,解决脏写,脏读和不可重复读(mvcc读快照)
串行化(不推荐):串行执行,解决所有并发问题 -
锁
读读:一般共享锁(可读不可写),select for update可以给读读加排他锁
读写或写写:只要有写在,一定加排他锁(不能读也不能写) -
点查:根据索引查询某行数据,一般通过唯一索引查询