其实不论客户端进程和服务器进程是采用哪种方式进行通信,最后实现的效果都是:客户端进程向服务器进程发送一段文本(MySQL语句),服务器进程处理后再向客户端进程发送一段文本(处理结果)。那服务器进程对客户端进程发送的请求做了什么处理,才能产
生最后的处理结果呢?
包括连接器、查询缓存、分析器、优化器、执行器等,涵盖MySQL 的大多数核心服务功能,以及所有的内置函数(如日期、时间、数学和加密函数等),所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图等
负责数据的存储和提取,其架构模式是插件式的,支持InnoDB、MyISAM、Memory等多个存储引擎
mysql -h$ip -P$port -u$user -p
都将依赖于此时读到的权限【取与用】
连接完成后,如果我们没有后续的动作,这个连接就处于空闲状态【show processlist】
其中的Command列显示为“Sleep”的这几行,表示现在系统里面存在几个空闲连接。
MySQL将缓存存放在一个引用表中,通过一个哈希值引用,这个哈希值包括了以下因素,即查询本身、当前要查询的数据库、客户端协议的版本等一些其他可能影响返回结果的信息。
缓存命中
请求在任何字符上的不同(例如:空格、注释、大小写)
包含系统函数、用户自定义变量和函数、一些系统表
缓存失效
表的结构或者数据被修改(增删改、表结构调整)
按需使用 参数query_cache_type设置成DEMAND(默认不使用查询缓存)
mysql> select SQL_CACHE * from T where ID = 10;
词法分析: select识别出查询语句,把字符串“T”识别成“表名T”,把字符串“ID”识别成“字段ID”
语法分析: 是否满足SQL的语法规则,You have an error in your SQL syntax
查询优化器目标:
将解析树转化成执行计划
一条查询有多种执行方法(结果相同),找到这其中最好的执行计划
衡量方法
基于成本的查询优化器(Cost-Based Optimizer,CBO)
尝试预测一个查询使用某种执行计划时的成本,并选择其中成本最少的一个
依赖:
根据优化规则对关系表达式进行转换(多执行计划)
统计信息和代价模型(成本计算)
mysql> select * from T1 t1 join T2 t2 using(ID) where t1.c = 10 and t2.d = 20;
(1)既可以先从表t1里取出c等于10对应记录的ID值,在根据ID值关联t2表中d值等于20的记录
(2)也可以先从表t2中找到d值等于20的记录对应的ID值,在根据ID值关联t1表中c等于10的记录
这两种执行方法的结果是一样的,但是执行的效率会有不同,而优化器的作用就是决定使用哪一种方案
统计信息的准确与否、代价模型的合理与否都会影响CBO选择最优计划
各种不同的存储引擎向上边的MySQL server层提供统一的调用接口(也就是存储引擎API),包含了几十个底层函数,像"读取索引第一条内容"、“读取索引下一条内容”、"插入记录"等等。
创建、打开和关闭表
对表加锁
全表扫描
通过索引访问table内容
事务处
查询权限判断
API获取数据
(1)调用InnoDB引擎接口取这张表的第一行,判断ID是否满足条件,如果是则将结果缓存到结果集中,否则跳过
(2)调用引擎接口取“下一行”,重复相同的逻辑判断,直到取到这个表的最后一行。
(3)执行器将上述过程中筛选出来的满足条件的记录行组成的记录及作为结果集返回给客户端
MySQL server层的核心组件:连接器、查询缓存、分析器、优化器、执行器