01 | 基础架构:一条SQL查询语句是如何执行的?

不要直接陷入细节里,先鸟瞰其全貌,从高维度理解问题。执行mysql> select  * from T where ID=10;

输入语句,返回结果,内部的执行过程。 MySQL 拆解一下

下面我给出的是 MySQL 的基本架构示意图,从中你可以清楚地看到 SQL 语句在 MySQL 的各个功能模块中的执行过程。

MySQL的逻辑架构图

分为

1、Server 层:

连接器、查询缓存、分析器、优化器、执行器等,核心服务功能、内置函数(如日期、时间、数学和加密函数等),所有跨存储引擎的功能都在这一层实现,比如存储过程、触发器、视图等。

2、存储引擎层:

数据的存储和提取。插件式、支持 InnoDB(最常用,MySQL 5.5.5 开始默认)、MyISAM、Memory 等多个存储引擎。

create table不指定引擎类型,就是 InnoDB。也可指定engine=memory,。不同存储引擎的表数据存取方式支持功能都不同

共用一个Server ,连接器到执行器的部分。整个执行流程:

一、连接器

跟客户端(1)建立连接、获取权限、维持管理连接。

(1)连接命令:mysql -h$ip  -P$port -u$user -p 

然后交互对话输入密码。也可-p 后写,生产不要这样防泄露。

命令中的 mysql 客户端工具,跟服务端建立连接。完成TCP 握手

(2)认证:输入用户名、密码。

不对,则收到"Access denied for user"的错误,客户端程序结束执行。

通过,连接器到权限表查。连接里权限判断逻辑,都依赖于此时读到的权限。

这意味着,成功建立连接后,权限修改不影响已经存在连接的权限。新建连接才生效

(3)如没后续动作,连接空闲状态,你可以在 show processlist 命令中看到它。Sleep表示

(4)客户端8 小时没动静自动断开wait_timeout 控制

断开之后,再请求提醒: Lost connection to MySQL server during query需重连

长连接:连成后,一直用。短连接:执行少就断开,重建

1、结论:建立连接复杂,尽量少建,多用长连接

2、问题:长连接多 MySQL 占内存涨得快,因为 MySQL 执行过程中临时用的内存连接对象里,断开才释放。内存占用太大,被系统强行杀掉(OOM),现象就是 MySQL 异常重启

3、解决方案:

(1)定期断开长连接。程序里判断执行过占用内存的大查询

(2)如 MySQL 5.7 或更新版本,执行大操作后,执行mysql_reset_connection 重新初始化。过程不需重连和权限验证,恢复到创建状态。

二、查询缓存

执行 select 语句,先查询缓存。

执行过的语句及结果以 key-value (key 是查询语句,value 是结果)在缓存在内存中。找到 key, value 直接返回。不在则执行。完成后存入查询缓存。

大多数情况不要用查询缓存,弊大于利。

失效频繁,更新表,查询缓存清空(这个表上)。更新大,查询命中率低。比如系统配置表适合。

按需使用:query_cache_type 设置成 DEMAND,默认不使用。用 SQL_CACHE 显式指定

mysql> select  SQL_CACHE * from T where ID=10;

MySQL 8.0 没有这个功能

三、分析器

真正执行语句。MySQL 要知道你要做什么,做解析。

(1)词法分析:多个字符串、空格,识别出是什么,代表什么。针对关键字

MySQL 从你输入的"select"这个关键字识别出查询语句。它也要把字符串“T”识别成“表名 T”,把字符串“ID”识别成“列 ID”。

(2)识别后,做“语法分析”。是否满足 MySQL 语法,不对收到“You have an error in your SQL syntax”的错误提醒

ERROR 1064  (42000): You have an error in your SQL syntax; check the manual that  corresponds to your MySQL server version for the right syntax to use near  'elect * from t where ID=1' at line 1

提示第一个出现错误的位置,关注紧接“use near”

四、优化器

多个索引时,决定用哪个;多表关联(join)时,决定连接顺序

mysql> select  * from t1 join t2 using(ID)  where  t1.c=10 and t2.d=20;

既可以先从表 t1 里面取出 c=10 的记录的 ID 值,再根据 ID 值关联到表 t2,再判断 t2 里面 d 的值是否等于 20。

也可以先从表 t2 里面取出 d=20 的记录的 ID 值,再根据 ID 值关联到 t1,再判断 t1 里面 c 的值是否等于 10。

结果一样,效率不同

五、执行器

判断权限,没有,返回错误,ERROR 1142  (42000): SELECT command denied to user 'b'@'localhost' for table 'T'

有,打开表执行。打开表时,根据表的引擎定义使用引擎提供接口

例子表 T 中,ID 字段没有索引

1.  调用 InnoDB 引擎接口取表第一行,ID 值不是 10 则跳过,是则存在结果集中

2.  调用引擎接口取“下一行”,重复直到最后。

3.  执行器将满足条件行结果集返回给客户端。

有索引表,执行逻辑一样。取满足条件第一行,之后下一行,接口是引擎中已经定义好。

慢查询日志rows_examined,表示扫描多少行,调用引擎获取数据行时累加的。

有些场景下,执行器调一次,在引擎内部则扫描了多行,因此引擎扫描行数跟 rows_examined 并不是完全相同的。

小结

表 T 中没有字段 k, select * from T where k=1,  “Unknown column ‘k’ in ‘where clause’”。哪个阶段报出来?分析器

评论1

1. MySQL的框架有几个组件, 各是什么作用? 

2. Server层和存储引擎层各是什么作用?

3. you have an error in your SQL syntax 这个保存是在词法分析里还是在语法分析里报错?

4. 对于表的操作权限验证在哪里进行?

5. 执行器的执行查询语句的流程是什么样的? 

评论2(简短总结)

客户端连接到服务端,获取到权限等信息, 然后在连接的有效时长内(interactive_timeout和wait_timeout参数控制, 5.7版本会断开可以自动重连)对sql进行处理。

首先会判断查询缓存是否开启,如果已经开启,会判断sql是select还是update/insert/delete,对于select,尝试去查询缓存,如果命中缓存直接返回数据给客户端, 如果缓存没有命中,或者没有开启缓存, 会进入到下一步分析器。

分析器进行语法分析、词法分析,检查sql的语法顺序等得到解析树, 然后预处理器对解析树进一步分析,验证数据表、字段是否存在,通关之后sql进入下一步优化器,所以课后问题一定是分析器阶段了。

优化器对sql执行计划分析, 得到最终执行计划,得到优化后的执行计划之后交给执行器。

执行器调用存储引擎api执行sql,得到响应结果, 将结果返回给客户端,如果缓存是开启状态, 会更新缓存。

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