此图摘自极客时间丁奇老师的MySQL实战45讲
简单介绍一下这个图
平时我们使用java去连接数据库时,要使用一个连接池来维护多个数据库连接,我们的一条sql语句通过一个连接发往数据库进行查询。
发送sql语句请求的就是我们的客户端,接受请求的就是我们的mysql数据库server层
现在开始介绍上图的结构:
MySQL大致分为server层和存储引擎层。
server层又包括上图中的连接器、分析器、优化器和执行器,其中缓存现在用的比较少了。
存储引擎层负责数据的存储和读取,可以支持InnoDB、MyISAM、Memory等多个引擎,目前用的比较多的InnoDB,也是默认引擎。
查询语句怎么执行的
下面从一条查询语句的执行过程来介绍server层的几个部件:
1. 首先需要和数据库建立连接
这个操作是连接器负责的,它负责和客户端建立连接、获得权限、维持和管理连接。
这个操作开始是TCP三次握手,TCP连接之后,连接器开始认证你的用户名密码(密码不对会收到一个错误);
密码通过后,会验证用户的权限,在权限表里查询这个用户的权限;(如果使用这个连接过程中修改了用户权限,只有新的连接建立才会使用新权限,不会影响这个连接)
此时,mysql可以去做查询了。
介绍一下mysql的长连接和短链接:
长连接:客户端有持续的请求,一直使用同一个连接
短链接:一个连接只执行几个请求就断开连接
使用时尽量使用长连接,因为建立连接的过程很复杂很耗费资源;但也全部使用长连接,也会出现一个问题:MySQL占用内存涨得很快。这是因为mysql使用过程中的临时内存在连接对象里管理,而连接对象在断开连接时才会被释放。
2. 连接建立后,本该去缓存查询
本来是先去缓存进行查询,查询不到的话再去执行下面的操作
但现在不建议使用缓存!
原因:
缓存设计采用键-值对,查询语句作为键,结果作为值,查询很快,本应该使用缓存的,但是,一旦执行一条更新语句的话,整个缓存都会被清空,之前的缓存白存了。
3. 建立连接后,进入到分析器
这里开始执行语句。
分析器先进行词法分析:分析每一个词,识别出select判断是一个查询语句,识别出表名,识别出列名
然后进行语法分析:根据语法规则分析此sql语句是否符合mysql语法。
此时,mysql知道你要做什么了。
4. 进入优化器
优化器的作用:表中有多个索引时,决定使用哪个索引;多表连接时,决定表的连接顺序
优化器会对查询做一定的优化,确定语句的执行方案。
此时,mysql知道怎么去做了。
5. 进入执行器
执行前,首先查询用户对此表是否有权限,有权限就打开此表继续执行(没权限返回错误)
引擎会提供读写接口给执行器,执行器调用即可。
对于查询字段,如果没有索引:
- 调用InnoDB引擎的接口,取第一行,判断是否符合条件
- 调用接口取下一行,判断,一直遍历到最后一行
- 把结果返回给客户端。执行完成
如果有索引:
调用“满足条件的第一行”接口,再依次调用“满足条件的下一行”接口,然后返回
丁老师留的问题:如果表T中没有字段k,而你执行了这个语句 select * from T where k=1, 那肯定是会报“不存在这个列”的错误: “Unknown column ‘k’ in ‘where clause’”。你觉得这个错误是在我们上面提到的哪个阶段报出来的呢?