目录
一、Mysql架构分层
二、连接层
2.1.连接管理
2.2.身份验证
三、Server层
3.1.查询缓存
3.1.1 缓存的作用
3.1.2.为什么废弃缓存?
3.2.分析器
3.3.优化器
3.4.执行器
大家好,我是DarkKing,从上篇我们了解到mysql的基础架构。那么他们每个组件都是什么作用以及如何协作的呢?每个组件都具备什么样的能力?我们从一条SQL语句执行来说起。
从下图可以看出来,mysql的基础架构主要分为三层,连接层,server层以及存储引擎层。
连接层:连接器
server层:缓存,分析器,优化器,执行器
存储引擎:常用的择优innoDB和MyISAM引擎。
那么当我们要执行如下的一条SQL语句时,他是经过一个什么样的流程得到我们需要的结果的呢?
MariaDB [test]> select id,name,sex from user_info where id =1;
我们要执行一条SQL语句,首先要与mysql建立链接,那么连接的接受和创建就是由连接层处理的。
当 MySQL 启动(MySQL 服务器就是一个进程),等待客户端连接,每一个 客户端连接请求,服务器都会新建一个线程处理(如果是线程池的话,则是分配 一个空的线程),每个线程独立,拥有各自的内存处理空间。
可以通过
show processlist 命令查看连接,如下
当连接到服务器,服务器需要对其进行验证,也就是用户名、IP 、密码验证, 一旦连接成功,还要验证是否具有执行某个特定查询的权限(例如,是否允许客 户端对某个数据库某个表的某个操作)。
通过以下命令进行身份验证
mysql -h$ip -P$port -u$user -p
因此,连接器的主要作用是用来建立以及维护客户端的连接以及对连接进行身份权限验证的。
当客户端与mysql建立好连接之后,接下来就开始对sql进行处理。SQL的处理流程如下:
从图中我们可以看到,这一层主要功能有:SQL 语句的解析、优化,缓存的查询,sql的执行。
在Server层接受到一个SQL时,如果是查询语句,则首先会查询缓存,mysql会默认将上次SQL执行的语句当做key,结果当做value保存在内存里。如果下次查询直接命中key,则会直接返回客户端。如果没有命中,则会继续执行后面的流程。
缓存的一些参数配置如下:
query_cache_type 只能配置在 my.cnf 文件中,这大大限制了 qc 的作用 在生产环境建议不开启,除非经常有sql完全一模一样的查询
QC 严格要求 2 次 SQL 请求要完全一样,包括 SQL 语句,连接的数据库、协议 版本、字符集等因素都会影响。
不过从 8.0 开始,MySQL 不再使用查询缓存,那么放弃它的原因是什么呢?
MySQL 查询缓存是查询结果缓存。它将以SEL 开头的查询与哈希表进行比较, 如果匹配,则返回上一次查询的结果。进行匹配时,查询必须逐字节匹配,例如 SELECT * FROM e 1; 不等于 select * from e 1; ,此外,一些不确定的查询结果无法 被缓存,任何对表的修改都会导致这些表的所有缓存无效。因此,适用于查询缓 存的最理想的方案是只读,特别是需要检查数百万行后仅返回数行的复杂查询。 如果你的查询符合这样一个特点,开启查询缓存会提升你的查询性能
随着技术的进步,经过时间的考验,MySQL 的工程团队发现启用缓存的好处 并不多。首先,查询缓存的效果取决于缓存的命中率,只有命中缓存的查询效果才能 有改善,因此无法预测其性能。其次,查询缓存的另一个大问题是它受到单个互斥锁的保护。在具有多个内 核的服务器上,大量查询会导致大量的互斥锁争用。
通过基准测试发现,大多数工作负载最好禁用查询缓存(5.6 的默认设置): 按照官方所说的:造成的问题比它解决问题要多的多, 弊大于利就直接砍掉了
所以在大多数情况下,建议不开启mysql的缓存
当查询没有命中缓存的时候,则下一站就到了分析器,分析器主要作用就是对词法和语法进行分析。
首先分析器会对sql的词法进行分析,分析出里面的字符串都代表着含义,以及识别出来对应的关键字。
当做完了词法分析识别之后就要进行语法分析,根据语法的规则来判断输出的sql是否满足mysql的语法。如果不满足,则会提示You have an error in your SQL syntax;
在经过语法分析之后,mysql就知道要执行什么了,但是执行之前,要经过sql的优化器处理。例如重写查询,决定表的读取顺序,以及选择需要 的索引等。这一阶段用户是可以查询的,查询服务器优化器是如何进行优化的, 便于用户重构查询和修改相关配置,达到最优化。这一阶段还涉及到存储引擎, 优化器会询问存储引擎,比如某个操作的开销信息、是否对特定索引有查询优化 等。
sql经过优化之后,达到可执行阶段,之后交给执行器去处理。但是开始执行前还是要判断下当前用户是否有操作表的权限,如果有权限则会打开表继续执行。打开表的时候执行器就会根据表的不同引擎,去使用引擎的不同接口。
最后一个表的引擎比较多,我们放到下章详细介绍一下。不同的场景选择不同表的引擎是非常重要的。