天天都在跟 mysql 打交道,你知道执行一条简单的 select 语句,都经历了哪些过程吗?mysql
首先,mysql 主要是由 server 层和存储层两部分构成的。server 层主要包括链接器、查询缓存,分析器、优化器、执行器。存储层主要是用来存储和查询数据的,经常使用的存储引擎有 InnoDB、MyISAM,MySQL 5.5.5版本后使用 InnoDB 做为默认存储引擎。sql
链接器缓存
链接器主要负责将 mysql 客户端和服务端创建链接,链接成功后,会获取当前链接用户的权限。这里获取到的权限对整个链接都有效,一旦链接成功后,若是使用管理员帐号对该用户更改权限,当前链接中的拥有的权限保持不变,只有等到下次从新链接才会更新权限。优化
查询缓存server
链接成功后,即开始要正式执行 select 语句了,可是在执行查询以前,mysql 会去看下有没有该条语句的缓存内容,若是有缓存直接从缓存中读取并返回数据,再也不执行后面的步骤了,结束查询操做。索引
若是没有缓存则继续日后执行,并将执行结果和语句保存在缓存中。接口
注意在 mysql8 后已经没有查询缓存这个功能了,由于这个缓存很是容易被清空掉,命中率比较低。只要对表有一个更新,这个表上的全部缓存就会被清空,所以你刚缓存下来的内容,还没来得及用就被另外一个更新给清空了。效率
分析器原理
既然没有查到缓存,就须要开始执行 sql 语句了,在执行以前确定须要先对 sql 语句进行解析。分析器主要对 sql 语句进行语法和语义分析,检查单词是否拼写错误,还有检查要查询的表或字段是否存在。select
若是分析器检测出有错误就会返回相似 "You have an error in your sql" 这样的错误信息,并结束查询操做。
优化器
经过分析器以后,mysql 就算是理解了你要执行的操做了。一般对于同一个 sql 语句,mysql 内部可能存在多种执行方案,好比存在多个索引时,该选择哪一个索引,多个表关联查询时,怎么确认各个表的链接顺序。
这些方案的执行结果都同样,可是执行效率不同,因此 mysql 在执行以前须要尝试找出一个最优的方案来,这就是优化器的主要工做。可是 mysql 也会有选择错误方案的时候,这里暂不细说,留到后面再解释缘由。
执行器
通过优化器选定了一个方案后,执行器就按照选定的方案执行 sql 语句。前面咱们有讲过,在链接器中会读取当前用户的权限,链接器中只是获取权限而已,并无对权限进行判断和校验。
因此在执行器中,在执行语句以前会判断权限,若是没有对应的权限则会直接返回并提示没有相关权限。
这里你可能会问,为何不在链接器中就直接判断权限呢,这里我以为多是由于 mysql 要查询的表并不必定仅限于 sql 语句中字面上的那些表,有的时候可能须要通过分析器和优化器以后才能肯定到底要怎么执行,因此权限校验放在执行器中是有道理的。
注意若是是在前面的查询缓存中查到缓存以后,也会在返回结果前作权限校验的。
权限校验经过以后,就继续打开表,调用存储引擎提供的接口去查询并返回结果集数据。
到这里,一条查询 sql 语句就执行结束了。讲的比较粗糙,只是一个大体的流程,其中每一步在 mysql 的底层实现都很是复杂,后面再讲一讲索引的底层实现原理。