对于MySQL而言,其实分为客户端与服务端。java
服务端,就是MySQL应用,当咱们使用net start mysql命令启动的服务,其实就是启动了MySQL的服务端。mysql
客户端,负责发送请求到服务端并从服务端获取数据,客户端能够有多种形式,能够是咱们经过mysql -uroot -p1234打开的黑窗口,也能够是咱们使用的Nativecat、SQLyog等数据库链接工具,甚至咱们的程序,也能够称做MySQL的客户端。sql
而当咱们在mysql窗口或者数据库链接工具中输入一句sql后,咱们就能够获取到想要的数据,这中间MySQL究竟是怎么工做的呢?数据库
在咱们执行SQL后,例如一句简单的select * from user where name = ‘yanger’,客户端发送请求到服务端,请求到达Server层,会通过链接器、查询缓存、分析器、优化器、执行器等,最终经过存储引擎从文件系统获取数据或者插入数据到文件系统。缓存
在客户端程序发起链接的时候,须要携带主机信息、用户名、密码,服务器程序会对客户端程序提供的这些信息进行认证,若是认证失败,服务器程序会拒绝链接。服务器
链接命令你们都比较熟悉。网络
mysql -h$ip -P$port -u$user -p
输完命令以后,须要继续输入密码,密码也能够直接跟在 -p 后面,但这样可能会致使你的密码泄露,若是你连的是生产服务器,强烈建议你不要这么作。工具
MySQL采用TCP做为服务器和客户端之间的网络通讯协议,完成 TCP 握手后,链接器主要作密码校验和权限获取。优化
若是用户名或密码不对,你就会收到一个"Access denied for user"的错误3d
若是用户名密码认证经过,链接器会到权限表里面查出你拥有的权限。以后,这个链接里面的权限判断逻辑,都将依赖于此时读到的权限
MySQL的默认链接是8小时,由参数 wait_timeout 控制的,若是超过这个时间不使用,会自动断开,并在以后的操做中,抛出Lost connection to MySQL server during query的错误。
针对于查询语句,MySQL 拿到一个查询请求后,会先到查询缓存看看,以前是否是执行过这条语句,以前执行过的语句及其结果可能会以 key-value 对的形式,被直接缓存在内存中。若是命中缓存,将直接返回结果。若是不在查询缓存中,就会继续后面的执行阶段。执行完成后,执行结果会被存入查询缓存中。
针对于更新语句,包含插入删除语句,MySQL 收到更新请求时,会把查询缓存中该表相关的缓存数据所有清空。
咱们能够看到,只要有更新,缓存就会失效,而对于正常的业务,更新实际上是比较频繁的,也就是说,其实MySQL的查询缓存命中率并不会很高,因此建议通常不到开启。
能够经过设置 query_cache_type 为 DEMAND 来关闭查询缓存功能。而事实上,在 MySQL 8.0 版本,更是直接移除了查询缓存这一个功能。
MySQL 首先须要对SQL语句进行分析,分析过程本质上算是一个编译过程,涉及词法解析、语法分析、语义分析等阶段,经过分析MySQL知道本身要作什么。
若是语句不对,就会收到“You have an error in your SQL syntax”的错误提醒,通常语法错误会提示第一个出现错误的位置,因此你要关注的是紧接“use near”的内容。
面对分析器拿到的结果,MySQL会作一些优化处理,例如在表里面有多个索引的时候,决定使用哪一个索引,或者在一个语句有多表关联(join)的时候,决定各个表的链接顺序。
优化的结果就是生成一个执行计划,这个执行计划代表了应该使用哪些索引进行查询,表之间的链接顺序是啥样的。咱们可使用EXPLAIN语句来查看某个语句的执行计划。
这里\G在命令窗口没法一行时,能够竖着展现结果,方便查看。
通过了分析器和优化器,就正式进行执行阶段了,不过执行以前,须要作权限验证,若是权限不足,就会抛出权限的错误。其实在查询缓存的时候,同样也会进行权限校验。
若是经过验证,执行器就打开表继续执行。打开表的时候,执行器就会根据表的引擎定义,去使用这个引擎提供的接口。
MySQL支持很是多种存储引擎,经常使用的是InnoDB和MyISAM,MySQL的默认存储引擎是InnoDB。
假如咱们选择是InnoDB引擎,对于查询,那InnoDB 会取这个表的第一行来进行判断是否是符合要求,符合则存在结果集中,不然继续进行下一行,直到该表的最后一行。
而后存储引擎将结果返回给执行器, 执行器拿着结果返回给客户端,这样一句SQL就执行完成了。