前言
作为一名菜鸟程序员,我已经工作两年了。从事后端开发工作。
后端开发中,MySQL 可以说是必会的一门技能了。刚开始时我以为数据库就是写写 SQL 语句,做做增删改查业务。直到我写的程序多次导致 MySQL 出现死锁、大量慢查询、数据库压力过大等问题,我意识到对于数据库这门技术,了解它的性能优化以及内部原理是非常的重要。
这系列文章将会是我在学习 MySQL 过程中我学到的知识,我将从《高性能 MySQL》这本书,以及阅读网络上已有的其他 MySQL 教程中归纳总结,将我学到的知识记录在这里。
同时也分享给同样在学习的你。
那么开始学习吧~
MySQL 基本架构
我们执行一条 SQL 语句,查看它的返回结果,这个过程是怎么在 MySQL 内部执行的呢?这里先从 MySQL 的基本架构说起。
这张架构图从上到下分别代表客户端,Server 层和存储引擎层。
MySQL 大体上可以分为 Server 层和存储引擎层两部分。
Server 层包括连接器、分析器、优化器、执行器和查询缓存等。MySQL 中的大部分功能服务、所有的内置函数(CURDATE()、SUM()等)、存储过程、函数、触发器等功能,都是在这里实现的。
存储引擎层可以理解为对数据操作的功能部分,负责存储数据。我们熟知且常用的 InnoDB 引擎就在这里。从图中可以看出存储引擎不止有 InnoDB 一个,还有 MyISAM、Memory 等,不同的存储引擎共同使用同一个 Server 层。
查询语句在 MySQL 中执行过程是怎样的?
首先作为请求发起者,客户端与 MySQL 建立连接,这时候就是连接器在发挥作用。
1.连接器
连接器的作用就是跟客户端建立连接、检查权限、管理连接。
在客户端与 MySQL 服务端完成 TCP 三次握手后,连接器会对客户端的身份进行校验认证:检查客户端输入的用户名和密码。
如果用户名或者密码不正确,将会报错Access denied for user
。
认证通过后,连接器会查询出该客户端所拥有的数据库操作权限:是否可以查询、插入、更新、删除等等。之后进行的数据库操作是否有权限执行,就是依赖在这里读到的权限。
2.查询缓存
拿到 SQL 查询请求后,MySQL 会先看看缓存,如果之前执行过这个语句,就不需要在执行了,直接返回缓存里的结果。
如果没有命中缓存,就继续执行后面的操作,查询完毕后,结果会存入缓存中。
这个功能在 MySQL 8.0 被删除了。
如果用的是 5.x 版本,多数情况下缓存也不建议使用。因为当一个表更新了,这个表的查询缓存就都被清掉了,频繁更新的表基本上没有太多机会命中缓存。如果是很久不会变更数据的配置表,倒是比较适合做查询缓存。
3.分析器
开始执行语句,MySQL 要对 SQL 语句做解析工作,来知道你想通过 SQL 表达什么,让 MySQL 做什么。
首先是识别出你的 SQL 字符串语句每个词汇、空格组合在一起代表什么。把关键字 SELECT 识别出来要做查询语句,把 id 识别出是这个表的主键字段等等。
然后分析出这条 SQL 语句是否有语法错误,比如关键字是不是写错了。
完整正确的 SQL 就会通过分析器,走到下一步。
4.优化器
现在 SQL 是对的了,MySQL 优化器会生成一个执行计划。
使用哪个索引?
JOIN 语句关联的查询顺序?
怎么查询效率高?
这就是优化器的作用。
5.执行器
此时经过优化器,MySQL 知道怎么执行这条 SQL 语句,执行器这里就来执行它。
此时判断你的权限,比如这条语句要 SELECT,但是账号没有这个权限(连接器阶段查得),就会报错。
有权限,就继续执行。
SELECT * FROM student WHERE student_name = 'Tom';
比如这个 SQL,假设 student_name
字段没有索引,就会调用存储引擎从第一条开始查,如果学生名字是 Tom
, 就把这行存在结果集,不是就不存并跳过。
接下来查看下一行,重复上一步的操作,直到读完整个表,到最后一行退出。
最后执行器会把结果集存的记录返回给客户端。
到这里,整个 SQL 执行过程就结束了。
经过这么一分析,是不是感觉对 MySQL 更了解了呢?:-)