MySQL体系架构
可以看出MySQL是由连接池、管理工具和服务、SQL接口、解析器、优化器、缓存、存储引擎、文件系统组成。
连接池
由于每次建立建立需要消耗很多时间,连接池的作用就是将这些连接缓存下来,下次可以直接用已经建立好的连接,提升服务器性能。
管理工具和服务
系统管理和控制工具,例如备份恢复、Mysql复制、集群等
SQL接口
接受用户的SQL命令,并且返回用户需要查询的结果。比如select ... from就是调用SQL接口
解析器
SQL命令传递到解析器的时候会被解析器验证和解析。解析器主要功能:1、将SQL语句分解成数据结构,后续步骤的传递和处理就是基于这个结构的。2、将SQL语句分解成数据结构,后续步骤的传递和处理就是基于这个结构的。
优化器
查询优化器,SQL语句在查询之前会使用查询优化器对查询进行优化。
缓存器
查询缓存,如果查询缓存有命中的查询结果,查询语句就可以直接去查询缓存中取数据。这个缓存机制是由一系列小缓存组成的。比如表缓存,记录缓存,key缓存,权限缓存等。
存储引擎(后面单独说)
文件系统(后面单独说讲)
连接层
当MySQL启动(MySQL服务器就是一个进程),等待客户端连接,每一个客户端连接请求,服务器进程会创建一个线程专门处理与这个客户端的交互。当客户端与该服务器断开之后,不会立即撤销线程,只会把他缓存起来等待下一个客户端请求连接的时候,将其分配给该客户端。每个线程独立,拥有各自的内存处理空间。
以下命令可以查看最大的连接数:
show VARIABLES like '%max_connections%'
连接到服务器,服务器需要对其进行验证,也就是用户名、IP、密码验证,一旦连接成功,还要验证是否具有执行某个特定查询的权限(例如,是否允许客户端对某个数据库某个表的某个操作)
Server层(SQL处理层)
这一层主要功能有:SQL语句的解析、优化,缓存的查询,MySQL内置函数的实现,跨存储引擎功能(所谓跨存储引擎就是说每个引擎都需提供的功能(引擎需对外提供接口)),例如:存储过程、触发器、视图等。
当然作为一个SQL的执行流程如下:
1.如果是查询语句(select语句),首先会查询缓存是否已有相应结果,有则返回结果,无则进行下一步(如果不是查询语句,同样调到下一步)
2.解析查询,创建一个内部数据结构(解析树),这个解析树主要用来SQL语句的语义与语法解析;
3.优化:优化SQL语句,例如重写查询,决定表的读取顺序,以及选择需要的索引等。这一阶段用户是可以查询的,查询服务器优化器是如何进行优化的,便于用户重构查询和修改相关配置,达到最优化。这一阶段还涉及到存储引擎,优化器会询问存储引擎,比如某个操作的开销信息、是否对特定索引有查询优化等。
缓存(了解即可)
show variables like '%query_cache_type%' -- 默认不开启
show variables like '%query_cache_size%' --默认值1M
SET GLOBAL query_cache_type = 1; --会报错
query_cache_type只能配置在my.cnf文件中!
缓存在生产环境建议不开启,除非经常有sql完全一模一样的查询
缓存 严格要求2次SQL请求要完全一样,包括SQL语句,连接的数据库、协议版本、字符集等因素都会影响
从8.0开始,MySQL不再使用查询缓存,那么放弃它的原因是什么呢?
MySQL查询缓存是查询结果缓存。它将以SEL开头的查询与哈希表进行比较,如果匹配,则返回上一次查询的结果。进行匹配时,查询必须逐字节匹配,例如 SELECT * FROM e1; 不等于select * from e1;
此外,一些不确定的查询结果无法被缓存,任何对表的修改都会导致这些表的所有缓存无效。因此,适用于查询缓存的最理想的方案是只读,特别是需要检查数百万行后仅返回数行的复杂查询。如果你的查询符合这样一个特点,开启查询缓存会提升你的查询性能。
随着技术的进步,经过时间的考验,MySQL的工程团队发现启用缓存的好处并不多。
首先,查询缓存的效果取决于缓存的命中率,只有命中缓存的查询效果才能有改善,因此无法预测其性能。
其次,查询缓存的另一个大问题是它受到单个互斥锁的保护。在具有多个内核的服务器上,大量查询会导致大量的互斥锁争用。
通过基准测试发现,大多数工作负载最好禁用查询缓存(5.6的默认设置):按照官方所说的:造成的问题比它解决问题要多的多,弊大于利就直接砍掉了。