一、MySQL逻辑架构
MySQL 分层--主要为服务层和存储引擎层
1. 服务层
Server层包括连接器、查询缓存、分析器、优化器、执行器等,涵盖 MySQL 的大多数核心服务功能,以及所有的内置函数(如日期、时间、数学和加密函数等),所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图等。
连接器
连接器主要负责连接处理、授权认证、安全服务等功能的处理。
当客户端应用连接到MySQL服务器时,服务器需要对其进行认证,认证基于用户名,主机信息和密码('user_name'@'host_name'),如果使用了安全套接字(SSL)的方式连接,还可以使用证书验证,一旦客户端连接成功,服务器会继续验证该客户端是否具有某个特定查询的权限,并且这个连接里面的权限判断逻辑,都将依赖于此时读到的权限,也就是说,后续只要这个连接不断开,即时管理员修改了该用户的权限,该用户也是不受影响的。
查询缓存(MySQL 8.0 版本后移除)
查询缓存主要用来缓存我们所执行的 SELECT 语句以及该语句的结果集。
MySQL 查询不建议使用缓存,因为查询缓存失效在实际业务场景中可能会非常频繁
分析器
对 SQL 语句做解析,并判断SQL语句是否满足MySQL语法
1. 词法分析:一条 SQL 语句有多个字符串组成,首先要提取关键字,比如 select,提出查询的表,提出字段名,提出查询条件等等;
2. 语法分析:主要就是判断你输入的 sql 是否正确,是否符合 MySQL 的语法。
SQL语句的中关键字执行顺序
关键字简述:
- FROM:确定数据来源,即指定表;
- JOIN...ON:确定关联表和关联条件;
- WHERE:指定过滤条件,过滤出满足条件的数据;
- GROUP BY:按指定的字段对过滤后的数据进行分组;
- HAVING:对分组之后的数据指定过滤条件;
- SELECT:查找想要的字段数据;
- DISTINCT:针对查找出来的数据进行去重;
- ORDER BY:对去重后的数据指定字段进行排序;
- LIMIT:对去重后的数据限制获取到的条数,即分页;
作者:Code综艺圈 https://www.bilibili.com/read/cv10326120 出处:bilibili
优化器
多数情况下,一条查询可以有很多种执行方式,最后都返回相应的结果。优化器的作用就是找到这其中最好的执行计划。
优化手段包括:重写查询、决定表的读取顺序、提前终止查询,以及选择合适的索引等
而人为地干预优化器的执行主要有两种方法:
1. 特殊提示关键字(hint):例如强制索引(FORCE INDEX);
SELECT * FROM TABLE FORCE INDEX (FIELD1) …
2. 优化器解释(explain)优化过程:用户可以知道服务器是如何进行优化决策的,并提供一个参考基准,便于用户重构查询和schema,修改相关配置,是sql语句尽可能高效执行。
EXPLAIN SELECT * FROM TABLE WHERE …
一般实际开发过程中不会使用强制使用某个索引这种手段(索引改变会失效),而是通过影响优化器的执行
更多使用explain进行sql语句调优请看:MySQL执行计划
执行器
在完成解析和优化阶段以后,MySQL会生成对应的执行计划,首先执行前会校验该用户有没有权限,如果没有权限,就会返回错误信息,如果有权限,就会去调用引擎的接口,返回接口执行的结果,这些接口被称为handler API。
之所以在执行前还需要进行权限验证,是因为sql执行过程中可能会有触发器这种在运行时才能确定的过程,分析器工作结束后的precheck是不能对这种运行时涉及到的表进行权限校验的,所以需要在执行器阶段进行权限检查。
一条SQL语句在MySQL中执行过程
主要执行过程如下图所示,主要分为以下几个步骤:
- 客户端向MySQL服务器发送一条查询请求,连接器进行认证;
- 服务器首先检查查询缓存,如果命中缓存,则立刻返回存储在缓存中的结果,否则进入下一阶段;
- 分析器进行SQL解析生成语法树,然后通过预处理器(它用来判断解析树的语义是否正确,也就是表名和字段名是否存在)生成一个新的解析树;
- 优化器生成新的优化执行计划;
- MySQL根据新的执行计划,再次进行权限认证通过后调用存储引擎的API来执行查询;
- 将结果返回给客户端,同时缓存查询结果。
2. 存储引擎层
存储引擎负责MySQL中数据的存储和提取,和GNU/Linux下的各种文件系统一样,每个存储引擎都有它的优势和劣势。目前主要的MSQL引擎主要有(常用前三种):
- InnoDB存储引擎(MySQL的默认事务型引擎)
- MyISAM存储引擎(MySQL5.1及之前版本的默认引擎)
- Memory引擎
- Archive引擎
- NDB引擎
特性 | InnoDB | MyISAM | Memory | Archive | NDB |
---|---|---|---|---|---|
存储限制 | 64TB | 无 | 有 | 无 | 有 |
事务支持 | 支持 | ||||
锁级别 | 行锁 | 表锁 | 表锁 | 行锁 | 行锁 |
MVCC | 支持 | 支持 | 支持 | ||
Hash索引 | 支持 | 支持 | 支持 | ||
全文索引 | 支持 | ||||
集群索引 | 支持 | ||||
数据缓存和索引缓存 | 支持 | 支持 | 支持 | ||
数据压缩 | 支持 | 支持 | |||
批量插入速度 | 低 | 高 | 高 | 很高 | 高 |
空间使用 | 高 | 低 | N/A | 非常低 | 低 |
内存使用 | 高 | 低 | 中等 | 低 | 高 |
集群数据库支持 | 支持 | ||||
外键支持 | 支持 | ||||
适用场景 | 事务,行锁,大量读写,大型互联网应用 | 插入、更新少,读取频繁 | 数据量小,频繁访问,容忍数据丢失 | 数据归档,作为日志表 | 集群 |
InnoDB存储引擎
InnoDB是最重要,使用最广泛的存储引擎,它被设计用来处理大量的短期事务,短期事务大部分情况是正常提交的,很少会回滚。InnoDB的性能和自动崩溃恢复的特性,使得它在非事务型存储的需求也很流行。
- InnoDB表是基于聚集索引建立的。聚集索引对主键查询有很高的性能,不过它的二级索引(secondary index,非主键索引)中必须包含主键列,所以如果主键列很大的话,其他的所有索引列都会很大。因此,若表上的索引较多的话,主键应当尽可能的小。InnoDB的存储格式是平台独立的,也就是说可以将数据和索引文件从一个平台移到另一个平台。
- InnoDB采用MVCC(多版本并发控制)来支持高并发,并且实现了四个标准的隔离级别。其默认级别是REPEATABLE READ(可重复读),并且通过间隙锁(next-key locking)策略防止幻读的出现。间隙锁使得InnoDB不仅仅锁定查询涉及的行,还会对索引中的间隙进行锁定,以防止幻影行的插入。
- InnoDB内部做了很多优化,包括从磁盘读取数据时采用的可预测预读,能够自动在内存中创建hash索引以加速读操作的自适应哈希索引(adaptive hash index),以及能够加速插入操作的插入缓冲区(insert buffer)等。
MyISAM存储引擎
MyISAM提供了大量的特性,包括全文索引、压缩、空间函数(GIS)等,但MyISAM不支持事务和行级锁,而且有一个毫无疑问的缺陷就是崩溃后无法安全恢复。尽管MyISAM引擎不支持事务和崩溃后的恢复,但它绝不是一无是处的。对于只读的数据,或者表比较小,可以忍受修复(repair)操作,则依然可以继续使用MyISAM。
- MyISAM会将表存储在两个文件中:数据文件和索引文件,分别以.MYD和.MYI为拓展名。MyISAM表可以包含动态或者静态(长度固定)行。MySQL会根据表的定义来决定采用何种格式,MyISAM表可以存储的行记录数,一般受限于可用的磁盘空间,或者操作系统中单个文件的最大尺寸。
- MyISAM对整张表加锁,而不是针对行。读取时会对需要读到的所有表加共享锁,写入时则对表加排他锁。但是在表有读取查询时,也可以往表中插入新的记录(这被称为并发插入)。
- 如果表在创建并导入数据以后,不会再进行修改操作,那么这样的表或许适合采用MyISAM压缩表。压缩表是不能进行修改的(除非先将表解除压缩,修改数据,然后再次压缩),压缩表可以极大地减少磁盘空间占用,因此也可以减少磁盘I/O,从而提升查询性能。压缩表也支持索引,但索引也是只读地。
MyISAM存储引擎
如果需要快速地访问数据,并且这些数据不会被修改,重启以后丢失也没有关系,那么使用Memory表是非常有用的。Memory表至少比MyISAM表要快一个数量级,因为所有的数据都保存在内存中,不需要进行磁盘I/O。Memory表的结构在重启以后还会保留,但是数据会丢失。
- Memory表支持Hash索引,因此查找操作非常快。Memory表是表级锁,因此并发写入的性能较低。
- Memory表在很多场景可以发挥很好的作用:用于查找或者映射表(例如邮编和地点映射的表);用于缓存周期性聚合数据;用于保存数据分析中产生的中间数据(例如在MySQL执行查询的过程中需要使用临时表来保存中间结果)。
文章有不当之处,欢迎指正。部分内容来源于网络,如有侵权请联系删除。