一条SQL查询语句是如何执行的?(sql查询语句能实现哪些查询功能)
1 背景
估计大家在各种面试中没少遇到被问:你给说一下一条SQL语句在MySQL中的执行过程吧.其实这也能看出面试者对MySQL整个体系架构的理解!
开局先来张图.MySQL的体系架构图:
2 一条select语句的执行过程
1 先经过连接层.连接器负责和客户端建立连接、获取权限、维持和管理连接.连接器会对你的用户名密码进行校验
通过之后会通过mysql的权限表对用户权限进行加载.
2 连接通过后来到分析器.分析器会对SQL语句进行分析.会对语句的语法语义进行检查.检查语句是否符合SQL规范.
3 优化器,优化器会对SQL语句进行执行计划分析.得到最合适的执行计划
4 先校验你的用户是否有这个表的对应权限.就是第一步连接器中加载的权限信息校验.然后就交给存储引擎去进行具体的操作.
存储引擎层:
1 先检查buffer pool中是否有对应的数据页.如果有的话就根据页目录找到对应的数据行进行返回数据.
2 如果buffer pool中没有.则根据优化器得出的执行计划.name列有索引的话则先对二级索引进行查询.得到对应的二级索引的叶子节点.然后根据叶子节点中记录的主键ID进行回表查询数据
3 得到聚簇索引的叶子节点之后加载到buffer pool中.然后根据页目录找到对应的数据行返回给客户端
4 如果name 列没有索引.则进行全表扫描
3 一条update语句的执行过程
update test set age=18 ande name='test' where sid='1001'
1 前边步骤和select一致.先找到对应的数据页和数据行
2 在 buffer pool中先记录update之前的undo日志.
3 将当前记录的主键写入undo
4 将undo的变化记录到redo中,redo将记录变化之前完整的聚簇索引对应的更改列的所有数据:例如(1,1001,18,test)
5 如果更新列是二级索引中的列.那么就把二级索引中对应的列标记为删除.同时二级索引中未变化的列记录undo和现在要更新的二级索引列组合成新的二级索引
放入change buffer中
6 将undo页面的修改再次记录到redo中
如果更新的值导致了列长度发生了变化
可以发现相对于name是test 现在的name列长度发生了变化
update test set age=18 ande name='Kobe Bean Bryant' where sid='1001'
这里相比于上边出现的不一样的是第四步
也就是redo记录聚簇索引变化不一样了.首先redo会将原主键列标记为删除.再重新插入一条主键数据(1,1001,18,Kobe Bean Bryant)
4 总结
这篇文章主要为大家分享了一条select及update语句在MySQL中的运行流程