MySQL语句是怎么实现的?需要进行合理的优化分析( 二 )

这条语句指定了MySQL服务器的地址为 127.0.0.1,也就是本机,端口号为3306,用户名为name,密码为password 。指定库名为database_name,指定默认字符集为utf8 。
2 完成连接后,如果开启了MySQL的缓存机制,这时候会先去查询缓存是否命中,如果缓存命中则直接返回缓存中的数据,如果缓存没有命中则继续向下执行 。
3 分析器会分析每个词是否是有意义的,比如会解析到 select 是SQL的关键词,t 是表名,id 和 name 是表名中的字段.然后分析SQL的语法是否正常,该条语句可以正常执行 。
4 优化器会分析在字段 id 和 name 上是否有索引,应该选择哪个索引 。如果表 t 是以 id 为主键,那么分析器就会直接走主键索引了 。
5 执行器开始执行前会先校验该用户是否有对该的读权限 。通过权限校验后,执行器会调用存储引擎的API查询出这条数据,返回给客户端 。
更新语句如何实现
一条更新语句的执行也要经历一条查询语句所要经历的几个阶段,连接器建立连接、分析器分析语法、优化器选择索引,执行器调用存储引擎的API,与查询语句相比,更新语句更为复杂,因为MySQL的InnoDB引擎要保证在数据库机器宕机以后数据不丢失 。
同样以一个例子来总结查询语句是如何实现的
update t set name = 'tom' where id = 123复制代码1 客户端与MySQL服务端建立网络连接
2 分析器解析出这是一条更新语句
3 优化器选择主键索引,假设以 id 做该表的主键
4 执行器首先查询内存中是否有表 t 中 id 等于123的这一行数据,如果没有则通过存储引擎将这行数据取到内存中
5 执行器修改 name 字段为tom,得到一个新的行
6 存储引擎将新行的数据写入内存,并写redo log日志,此时 redo log 处于 prepare 状态
7 执行器写bin log日志
8 存储引擎修改redo log日志为commit状态

MySQL语句是怎么实现的?需要进行合理的优化分析

文章插图
 
以上步骤就是一个完整的更新语句执行过程,细心的读者会发现更新的数据只写入到内存,还没有持久化到磁盘,mysql异步定期将内存中的数据写入到磁盘,这一过程和操作系统的文件系统读写很像,文件系统中有一个page cache,写文件时先写cache然后用一个独立的进程将数据刷到磁盘 。mysql使用了redo log日志,因此即使服务器宕机,数据也不会丢失,可以从redo log日志中恢复 。
 
redo log日志与bin log日志
1 redo log日志是由server层来写,bin log日志由存储引擎来写的;
2 redo log 是物理日志,记录的是“在某个数据页上做了什么修改",bin log用于记录逻辑操作 。在statement模式时,bin log记的就是SQL语句;
3 redo log日志循环写的,空间用完后,要先将数据刷到磁盘,然后清理空间 。bin log日志是追加写入的;
4 redo log日志用于数据库崩溃后恢复数据,而bin log日志则用于主备同步,数据备份等;
 




推荐阅读