Mysql-一条查询语句它到底是怎么执行的?

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: Mysql-一条查询语句它到底是怎么执行的?

image.png


1. 客户端/服务器通信协议


客户端和Mysql服务端建立连接



2. 查询缓存(Query Cache)


MySQL 内部自带了一个缓存模块。默认是关闭的。主要是因为 MySQL 自带的缓存的应用场景有限,第一个是它要求 SQL 语句必须一模一样。第二个是表里面任何一条数据发生变化的时候,这张表所有缓存都会失效。 在 MySQL 5.8 中,查询缓存已经被移除了。




3. 语法解析和预处理(Parser & Preprocessor)


下一步我们要做什么呢?


假如随便执行一个字符串 fkdljasklf ,服务器报了一个 1064 的错:

[Err] 1064 - 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 'fkdljasklf' at line 1\


服务器是怎么知道我输入的内容是错误的?或者,当我输入了一个语法完全正确的 SQL,但是表名不存在,它是怎么发现的?这个就是 MySQL 的 Parser 解析器和 Preprocessor 预处理模块。 这一步主要做的事情是对 SQL 语句进行词法和语法分析和语义的解析。


词法解析


词法分析就是把一个完整的 SQL 语句打碎成一个个的单词。

比如一个简单的 SQL 语句:

select name from user where id = 1;

它会打碎成 8 个符号,记录每个符号是什么类型,从哪里开始到哪里结束。


语法解析


第二步就是语法分析,语法分析会对 SQL 做一些语法检查,比如单引号有没有闭合,然后根据 MySQL 定义的语法规则,根据 SQL 语句生成一个数据结构。这个数据结构我们把它叫做解析树。


image.png

预处理器(Preprocessor)


如果表名错误,会在预处理器处理时报错。 它会检查生成的解析树,解决解析器无法解析的语义。比如,它会检查表和列名是否存在,检查名字和别名,保证没有歧义。




4. 查询优化器(Query Optimizer)


什么优化器?


问题:


一条 SQL 语句是不是只有一种执行方式?或者说数据库最终执行的 SQL 是不是就是我们发送 的 SQL?这个答案是否定的。一条 SQL 语句是可以有很多种执行方式的。但是如果有这么多种执行方式,这些执行方式怎么得到的?最终选择哪一种去执行?根据什么判断标准去选择? 这个就是 MySQL 的查询优化器的模块(Optimizer)。




5.执行计划


执行计划


查询优化器的目的就是根据解析树生成不同的执行计划,然后选择一种最优的执行计划,MySQL 里面使用的是基于开销(cost)的优化器,那种执行计划开销最小,就用哪种。


使用如下命令查看查询的开销:
    show status like 'Last_query_cost'; 
    --代表需要随机读取几个 4K 的数据页才能完成查找。 
复制代码


如果我们想知道优化器是怎么工作的,它生成了几种执行计划,每种执行计划的 cost 是多少,应该怎么做?


优化器是怎么得到执行计划的?


首先我们要启用优化器的追踪(默认是关闭的):


SHOW VARIABLES LIKE 'optimizer_trace'; 
set optimizer_trace="enabled=on"; 
复制代码


注意开启这开关是会消耗性能的,因为它要把优化分析的结果写到表里面,所以不要轻易开启,或者查看完之后关闭它(改成 off)。


接着我们执行一个 SQL 语句,优化器会生成执行计划:

select t.tcid from teacher t,teacher_contact tc where t.tcid = tc.tcid; 
复制代码


这个时候优化器分析的过程已经记录到系统表里面了,我们可以查询:

select * from information_schema.optimizer_trace\G 
复制代码


expanded_query 是优化后的 SQL 语句。

considered_execution_plans 里面列出了所有的执行计划。 
复制代码


记得关掉它:

set optimizer_trace="enabled=off"; 
  SHOW VARIABLES LIKE 'optimizer_trace'; 
复制代码



优化器可以做什么?


MySQL 的优化器能处理哪些优化类型呢?比如:

1、当我们对多张表进行关联查询的时候,以哪个表的数据作为基准表。 
2、select * from user where a=1 and b=2 and c=3,如果 c=3 的结果有 100 条,b=2 的结果有 200 条,    a=1 的结果有 300 条,你觉得会先执行哪个过滤? 
3、如果条件里面存在一些恒等或者恒不等的等式,是不是可以移除。 
4、查询数据,是不是能直接从索引里面取到值。 
5、count()、min()、max(),比如是不是能从索引里面直接取到值。 
6、其他。
复制代码


优化器得到的结果


优化器最终会把解析树变成一个查询执行计划,查询执行计划是一个数据结构。 当然,这个执行计划是不是一定是最优的执行计划呢?不一定,因为 MySQL 也有可能覆盖不到所有的执行计划。MySQL 提供了一个执行计划的工具。我们在 SQL 语句前面加上 EXPLAIN,就可以看到执行计划的信息。


EXPLAIN select name from user where id=1;



相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
21天前
|
关系型数据库 MySQL 数据库
轻松入门MySQL:精准查询,巧用WHERE与HAVING,数据库查询如虎添翼(7)
轻松入门MySQL:精准查询,巧用WHERE与HAVING,数据库查询如虎添翼(7)
|
22天前
|
SQL 关系型数据库 MySQL
【MySQL】11. 复合查询(重点)
【MySQL】11. 复合查询(重点)
20 0
|
23天前
|
SQL 关系型数据库 MySQL
mysql一条sql查询出多个统计结果
mysql一条sql查询出多个统计结果
14 0
|
21天前
|
缓存 关系型数据库 MySQL
MySQL查询优化:提速查询效率的13大秘籍(合理使用索引合并、优化配置参数、使用分区优化性能、避免不必要的排序和group by操作)(下)
MySQL查询优化:提速查询效率的13大秘籍(合理使用索引合并、优化配置参数、使用分区优化性能、避免不必要的排序和group by操作)(下)
|
21天前
|
缓存 关系型数据库 MySQL
MySQL 查询优化:提速查询效率的13大秘籍(索引设计、查询优化、缓存策略、子查询优化以及定期表分析和优化)(中)
MySQL 查询优化:提速查询效率的13大秘籍(索引设计、查询优化、缓存策略、子查询优化以及定期表分析和优化)(中)
|
5天前
|
SQL 关系型数据库 MySQL
mysql 数据库查询 查询字段用逗号隔开 关联另一个表并显示
mysql 数据库查询 查询字段用逗号隔开 关联另一个表并显示
17 2
|
7天前
|
关系型数据库 MySQL Shell
MySQL 查询
MySQL 查询
|
9天前
|
SQL 关系型数据库 MySQL
DQL语言之基础查询(mysql)
DQL语言之基础查询(mysql)
|
9天前
|
SQL 关系型数据库 MySQL
DQL语言之连接查询(mysql)
DQL语言之连接查询(mysql)
|
9天前
|
关系型数据库 MySQL
MySQL全局库表查询准确定位字段
information_schema.COLUMNS 详细信息查询
199 4