MySQL 基础技术(一) —— MySQL 是如何查询的?

之前,有一年多的工作客户端领域的工作经验。
后来,也在字节做了一年多的后端业务。
现在希望做一些 MySQL 总结,丰富一下自己在后端领域的积累。
目录如下:
MySQL 基础技术(一) —— MySQL 是如何查询的?
MySQL 基础技术(二) —— MySQL 是如何更新的?
MySQL 基础技术(三)—— MySQL 如何保证数据不丢失?
MySQL 基础技术(四)—— MySQL 如何保证高可用?


一、引子

在日常工作中,我们执行了一个简单的查询语句:

select * from <table_name> where id = 647;

那么,在 MySQL 内部会如何工作呢?

二、架构

首先,MySQL 架构可以分为 Server层Engine层两部分。

Server(服务)层:

涵盖了 MySQL 上层核心服务功能。
包括 “连接器”、“查询缓存”、“分析器”、“优化器”、“执行器”等等。
以及内置功能函数(数学、时间计算等等),触发器、视图等等跨存储引擎的功能都在 Server 层实现。

Engine(引擎)层:

主要负责数据的存储和提取等底层服务。
其实现是插件式的,MySQL 支持 InnoDBMyISAMMemory 等多个存储引擎。
目前,最常用的是 InnoDB 存储引擎。
而从 MySQL 5.5.5 版本开始,InnoDB 成为了默认存储引擎。

可以使用 show engines; 命令来查看各个引擎。

show engines;

几个常用底层存储引擎的简单区别:
InnoDB:支持事务,支持行锁,支持外键。
MyISAM:不支持事务,只支持表锁,不支持外键。
Memory:所有数据置于内存的存储引擎,拥有极高的插入,更新和查询效率。但是会占用和数据量成正比的内存空间。并且其内容会在 MySQL 重新启动时丢失。


三、架构图解

MySQL架构

接下来我们依次解释下各个组件:

1.连接器:

顾名思义,连接器负责跟客户端建立连接、获取权限、维持和管理链接的。

常用命令如下:

mysql -h$ip -P$port -u$user -p

在完成 TCP 握手后,连接器会基于用户名和密码来验证身份。
验证通过会查询出当前用户的权限。
(这代表:即使修改了用户权限,也只会影响下次连接时的权限。之前连接过的权限依然是旧的权限)

执行 show processlist; 可以查询当前的连接状态。

show processlist;

如果客户端长时间没有操作,连接器会自动断开。这个时间是由 wait_timeout 控制的,默认是8小时。

2.查询缓存

建立完连接之后,会优先查询有没有缓存。
在打开查询缓存的前提下,
每次执行过的 select 语句会以 Key - Value 的形式保存在内存中。
如果缓存命中,就会直接返回结果给客户端。

但是查询缓存往往弊大于利,得看场景使用。

查询缓存的失效非常频繁,只要表有更新,那么表上所有的查询缓存都会被清空。
大大降低了查询缓存的命中率,还牺牲了MySQL的部分性能。
除非是一种更新频率较低的静态表,可以打开查询缓存。(可以用SQL_CACHE显示制定。 如:select SQL_CACHE * from <table_name>)
更新频率比较高的表建议不要使用查询缓存。(query_cache_type 设置成 DEMAND)

注意:
MySQL 8.0 开始,已经废弃查询缓存功能。
因为缓存老是会被 update/insert/delete 操作清除掉,缓存了还没来得及用就又没了。

3.分析器

词法分析

首先,会进行词法分析。
将一个完整的SQL语句,拆分成语句类型(select? insert? update? ...)、表名、列名等等。

语法分析

其次,会进行语法分析。
判断 SQL 语句是否符合 MySQL 语法。
如果错误,会报出下面的错误:
ou have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ...
这时,我们只要修正 use near 后面的语句即可。

4.优化器

上一步,分析器通过“词法分析”、“语法分析”解析出这条 SQL 具体要做的事。
优化器,会基于这条 SQL 来分析具体要使用哪个索引方案。

具体可以使用 explain <sql>; 命令来分析 MySQL 的索引选择。
这个命令在优化 MySQL 查询效率时会经常用到。

例如:

explain select * from <table_name> where id = 647;

会分析出具体使用哪个索引方案,是否符合我们预期。
如果不符合我们的预期,可以使用 force index 命令来强制使用某个索引。(绝大部分场景下,MySQL选择的都是最优的)

5.执行器

分析器知道了 SQL 要做什么,
优化器明确了 SQL 需要用哪个索引方案。
执行器才会真正的基于索引方案,开始执行查询语句。

执行之前,会判断一下当前连接的用户有无该表的权限。
如果有权限,就会根据表的 Engine 选择来调用对应的引擎接口。

举例:
user_info 表的存储引擎是 InnoDB

select * from user_info where name = "647";

如果 name 列没有声明任何索引,执行步骤如下:

  1. 调用 innoDB 引擎接口获取表的第一行,判断 name 是否等于 647。如果不是,跳过。如果是,将结果保存。
  2. 调用 innoDB 引擎接口获取表的下一行,重复相同逻辑,一直到表的最后一行。
  3. 将所有满足条件的结果集返回给客户端。

如果 name 列有索引,执行步骤如下:

  1. 调用 innoDB 引擎接口获取索引树(B+树),基于索引树快速查到 name 等于 647 的所有主键id。
  2. 将所有满足条件的组件 id,回主表查详细信息。(这个操作称为“回表”)
  3. 将所有满足条件的结果集返回给客户端。

参考与致谢:
1.《MySQL实战45讲》(林晓斌老师)
2.《MySQL存储引擎对比》

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,417评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,921评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,850评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,945评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,069评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,188评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,239评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,994评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,409评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,735评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,898评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,578评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,205评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,916评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,156评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,722评论 2 363
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,781评论 2 351

推荐阅读更多精彩内容