Questions

查询执行流程是什么

  1. 建立连接

  2. 词法分析,语法分析

  3. 优化器,生成执行计划

  4. 执行器检查表权限

  5. 执行器调用存储引擎的接口,查询数据

  6. 如果命中覆盖索引,则走索引查询。否则顺序扫描,执行器不断调用存储引擎的接口获取下一行数据

  7. 执行器将结果返回给客户端

MySQL通过什么样的机制保证事务原子性?

  • undo log

B+树和B树的区别

  • B+树属于加强版的 B树,拥有 B树的所有优势

  • 最大的区别是只有叶子节点存数据,非叶子结点只存关键字;并且节点直接顺序排列

  • 优势:

    • 非叶子结点只存关键字,体积极小,索引可以整页的加载进内存中,查询很快。需要取数据时再读取硬盘,把页上的数据加载进内存

    • 节点直接通过指针相连,顺序读取能力、排序能力更强

B+树的叶节点的结构

手绘一个 B+ 树看看?

   _ 4 _ 7 _ 
  /     \   \
123     456 789

MySQL的排序过程是什么样的?

  • 排序字段命中索引:索引本身就是有序的,顺序遍历即可

  • 未命中索引:Using filesort

    • 数据量小时,内存排序(快排)

    • 数据量大时,外部文件排序(归并排序)

    • 如果有 LIMIT,会用大根堆 / 小根堆做堆排

    • 缓存区大小由参数配置

假如两个事务执行写操作,过程是什么样的?

假如事务1和事务2都要执行 update 操作

1 看有没有命中索引,2 看要更新的数据是不是有冲突。

  1. 命中索引

    1. 更新的行有冲突:事务1先 update 数据行的时候,先会获取行锁,锁定数据,当事务2要进行 update 操作的时候,也会尝试获取该数据行的行锁,但是已经被事务1占有,事务2只能等待

    2. 更新的行没有冲突:可以并行

  2. 没有命中索引的条件下,就获取所有行,都加上行锁,然后 MySQL 会再次过滤符合条件的的行并释放锁,只有符合条件的行才会继续持有锁。其余同上

自增ID用完了会怎么样?

如果表定义了自增ID作为主键,自增ID到达上限后不会再增长,再插入数据会报主键冲突的错误

如果未定义主键,InnoDB会自动帮你创建一个不可见的、长度为 6Brow_id,而且 InnoDB 维护了一个全局的 dictsys.row_id,所以未定义主键的表都共享该 row_id。该 row_id 实现上用的是 bigint unsigned 类型,但只保留了 6B = 48 bit ,就是说到达 6B 上限后会从 0 开始重新计数。可能导致主键冲突。

参考

方志朋 - MySQL 的自增 ID 用完了,怎么办?

Last updated