提示:文章内容来自《mysql是怎样运行的》以及部分B站宋红康老师的视频,这里仅仅是我的笔记,对重点内容的记录。强烈推荐购买这本书《mysql是怎样运行的》。
前言
首先提示读者,整个mysql系列都是根据《MySQL是怎样运行的》以及B站宋红康老师的视频进行学习后总结的,里面也包含了我对mysql的理解,如果有错误,希望大家能够在留言中指正。在看完《MYSQL是怎样运行的》之后,对于我的帮助真的很大,这个系列值的重点是在索引、事务以及锁上,未来还会继续更全面的更新mysql的相关知识,希望对你能够有一定的帮助。另外,mysql系列的内容,也是来自于我学习mysql高级部分中的笔记,这里仅仅是复盘。。。对重点内容进行总结,主要是形成一个mysql大体的认识,详细的情况可以看《mysql是怎么运行的》这本书
一、逻辑架构
在深入学习数据库Mysql之前,首先对mysql的服务架构,进行一个说明,好对mysql的中一条sql语句的执行过程有一个大体的认识。首先是对mysql的逻辑架构进行分析,如下图,就是最经典的mysql的逻辑架构图:
通常把mysql分为三层
1、连接层
客户端访问mysql之前,第一件事就是建立TCP连接,验证用户名密码等,连接建立后,mysql从线程池中分配一条线来执行后面的处理
2、服务层
首先服务层包含了四个部分
1)SQL interface:可以直接理解为SQL接口,它的作用就是用来接收用户的SQL命令,返回用户需要的查询结果
2)Parser:解析器,对用户的SQL指令进行语法分析和语义分析(SQL指令是否编写正确?这是一条什么类型的指令),生成一条语法树
3)Optimizer:优化器,优化器的作用就是分析解析器生成的语法树,确定SQL语句执行路径,生成执行计划。比如是否需要使用索引以及使用的是什么类型的索引,是聚簇索引还是非聚簇索引,表与表之间的连接计划是什么,哪个作为驱动表,哪个作为被驱动表(小表驱动大表),mysql会按照执行技术取执行,然后返回结果
4)Caches&Buffers:其实就是一个缓存区,会对已经执行的SQL的结果进行缓存,注意是对结果进行缓存,不是执行计划,但是这个缓存很鸡肋,SQL必须和被缓存的完全一样,缓存才会命中,即使一个空格都不行,因此mysql8开始,就不用缓存了,5.7以及之前,一条SQL执行之前都会先查缓存,执行后还要把缓存结果存入缓存
3、引擎层
真正负责了数据库中,数据的存储和提取,常见的存储引擎又InnoDB、MySIAM、MEMOR等,未来重点也是对InnoDB这个存储引擎做重点说明
二、一条sql语句怎么执行?
MySQL的查询流程:
1、查询缓存:一条sql进来后,首先第一步就是看看这个sql之前有没有查询过,但是大多数情况下,查询缓存就是一个鸡肋,因此mysql8之后也就抛弃了它。
为什么说查询缓存就是以一个鸡肋?
1)查询缓存缓存起来的是一条sql和其对应的查询结果,而不是缓存查询计划,一条sql进来后,首先判断这个尝试在缓存中,查看是否之前“来过”,如果“来过”,就直接返回结果,如果没有来过,就执行后面的(解析器—>优化器…);正应为它缓存起来的是一条sql,而不是执行计划,这就造成了鲁棒性大大降低,必须是同一条sql才能命中缓存,一个空格或者大小写的改变都会无法命中缓存
2)如果查询请求中包含某些系统函数、用户自定义变量和函数、一些系统表时,那这个请求就不会被缓存,以某些系统函数举例,可能同样的函数的两次调用会产生不一样的结果,比如函数 NOW ,每次调用都会产生最新的当前时间,如果在一个查询请求中调用了这个函数,那即使查询请求的文本信息都一样,那不同时间的两次查询也应该得到不同的结果,如果在第一次查询时就缓存了,那第二次查询的时候直接使用第一次查询的结果就是错误的!
3)缓存失效:如果某个表的结构或者数据发生改变,那么该表对应的所有查询缓存都会时效,比如对某个表执行,增删改,或者修改某个表的字段时候
总之,8.0之后 查询缓存就抛弃了
2、解析器:对SQL 语句进行语法分析、语义分析
其实就是分析一下我的sql语句有没有错误,分析sql的关键词,比如看见select就知道是查询,看见update就知道是更新(似乎解析器都是这个作用,类比下jvm的)
最终会生成这么语法树
3、优化器:这个优化器就比较重要了,mysql的优化器会比较各种执行方案的执行成本,它会先看看我们有没有使用索引,使用的索引是哪些;然后分析一下全表扫描的成本,分析下如果使用了索引,使用各个索引的执行成本,然后选择最小成本,作为我们的执行计划。总之就是根据解析器产生的语法树,分析各种执行成本,选择成本最低的生成一条执行计划,后面执行引擎也是根据这个执行计划,执行mysql的。后面我会对这部分怎么选择执行计划,做一个详细的说明,你就会体会到mysql的设计有多细节。。。整个mysql的设计过程中,都在尽力的节省空间,同时尽力减少IO次数,尽力的使用顺序IO,同时检索的时候,也是通过二分查找提高检索的速度的
4、执行器:简单的说就是根据执行计划执行sql的。
那么整个sql的执行流程大体上就是下面这张图:
其实在整个sql的执行过程,首先是客户端与mysql服务器经过TCP三次握手之后建立连接,mysql服务器会在线程池中拿一个线程和当前会话,然后在根据sql interface执行sql并获取结果的,这里只是对重点部分进行说明
三、show profile和show prodiles
1、查看最近的sql
2、查看当前会话
选择当前会话的哪条sql