- 建立连接
- 词法分析,语法分析
- 优化器,生成执行计划
- 执行器检查表权限
- 执行器调用存储引擎的接口,查询数据
- 如果命中覆盖索引,则走索引查询。否则顺序扫描,执行器不断调用存储引擎的接口获取下一行数据
- 执行器将结果返回给客户端
- undo log
- B+树属于加强版的 B树,拥有 B树的所有优势
- 最大的区别是只有叶子节点存数据,非叶子结点只存关键字;并且节点直接顺序排列
- 优势:
- 非叶子结点只存关键字,体积极小,索引可以整页的加载进内存中,查询很快。需要取数据时再读取硬盘,把页上的数据加载进内存
- 节点直接通过指针相连,顺序读取能力、排序能力更强
_ 4 _ 7 _
/ \ \
123 456 789
- 排序字段命中索引:索引本身就是有序的,顺序遍历即可
- 未命中索引:Using filesort
- 数据量小时,内存排序(快排)
- 数据量大时,外部文件排序(归并排序)
- 如果有
LIMIT
,会用大根堆 / 小根堆做堆排 - 缓存区大小由参数配置
假如事务1和事务2都要执行 update
操作
1 看有没有命中索引,2 看要更新的数据是不是有冲突。
- 命中索引
- 更新的行有冲突:事务1先
update
数据行的时候,先会获取行锁,锁定数据,当事务2要进行update
操作的时候,也会尝试获取该数据行的行锁,但是已经被事务1占有,事务2只能等待 - 更新的行没有冲突:可以并行
- 更新的行有冲突:事务1先
- 没有命中索引的条件下,就获取所有行,都加上行锁,然后 MySQL 会再次过滤符合条件的的行并释放锁,只有符合条件的行才会继续持有锁。其余同上
如果表定义了自增ID作为主键,自增ID到达上限后不会再增长,再插入数据会报主键冲突的错误
如果未定义主键,InnoDB会自动帮你创建一个不可见的、长度为 6B
的 row_id
,而且 InnoDB
维护了一个全局的 dictsys.row_id
,所以未定义主键的表都共享该 row_id
。该 row_id
实现上用的是 bigint unsigned
类型,但只保留了 6B = 48 bit
,就是说到达 6B
上限后会从 0 开始重新计数。可能导致主键冲突。