一条SELECT查询语句在数据库里执行时都经历了什么
每天都在跟 mysql 打交道,你知道执行一条简单的 select 语句,都经历了哪些过程吗?
首先,mysql 主要是由 server 层和存储层两部分构成的。server 层主要包括连接器、查询缓存,分析器、优化器、执行器。存储层主要是用来存储和查询数据的,常用的存储引擎有 InnoDB、MyISAM,MySQL 5.5.5版本后使用 InnoDB 作为默认存储引擎。
连接器
连接器主要负责将 mysql 客户端和服务端建立连接,连接成功后,会获取当前连接用户的权限。这里获取到的权限对整个连接都有效,一旦连接成功后,如果使用管理员账号对该用户更改权限,当前连接中的拥有的权限保持不变,只有等到下次重新连接才会更新权限。
查询缓存
连接成功后,即开始要正式执行 select 语句了,但是在执行查询之前,mysql 会去看下有没有该条语句的缓存内容,如果有缓存直接从缓存中读取并返回数据,不再执行后面的步骤了,结束查询操作。
如果没有缓存则继续往后执行,并将执行结果和语句保存在缓存中。
注意:在 mysql8 后已经没有查询缓存这个功能了,因为这个缓存非常容易被清空掉,命中率比较低。只要对表有一个更新,这个表上的所有缓存就会被清空,因此你刚缓存下来的内容,还没来得及用就被另一个更新给清空了。
分析器
既然没有查到缓存,就需要开始执行 sql 语句了,在执行之前肯定需要先对 sql 语句进行解析。分析器主要对 sql 语句进行语法和语义分析,检查单词是否拼写错误,还有检查要查询的表或字段是否存在。
如果分析器检测出有错误就会返回类似 "You have an error in your sql" 这样的错误信息,并结束查询操作。
优化器
通过分析器之后,mysql 就算是理解了你要执行的操作了。通常对于同一个 sql 语句,mysql 内部可能存在多种执行方案,比如存在多个索引时,该选择哪个索引,多个表关联查询时,怎么确认各个表的连接顺序。
这些方案的执行结果都一样,但是执行效率不一样,所以 mysql 在执行之前需要尝试找出一个最优的方案来,这就是优化器的主要工作。但是 mysql 也会有选择错误方案的时候,这里暂不细说,留到后面再解释原因。
执行器
经过优化器选定了一个方案后,执行器就按照选定的方案执行 sql 语句。前面我们有讲过,在连接器中会读取当前用户的权限,连接器中只是获取权限而已,并没有对权限进行判断和校验。
所以在执行器中,在执行语句之前会判断权限,如果没有对应的权限则会直接返回并提示没有相关权限。
这里你可能会问,为什么不在连接器中就直接判断权限呢,这里我觉得可能是因为 mysql 要查询的表并不一定仅限于 sql 语句中字面上的那些表,有的时候可能需要经过分析器和优化器之后才能确定到底要怎么执行,所以权限校验放在执行器中是有道理的。
注意如果是在前面的查询缓存中查到缓存之后,也会在返回结果前做权限校验的。
权限校验通过之后,就继续打开表,调用存储引擎提供的接口去查询并返回结果集数据。
到这里,一条查询 sql 语句就执行结束了。讲的比较粗糙,只是一个大致的流程,其中每一步在 mysql 的底层实现都非常复杂,需要逐步的深入了解。
耿小厨已开通个人微信公众号,想进一步沟通或想了解其他文章的同学可以关注我

一条SELECT查询语句在数据库里执行时都经历了什么的更多相关文章
- 1 基础架构:一条sql查询语句如何执行?
1 基础架构:一条sql查询语句如何执行? 分析一个最简单的查询 mysql> select * from T where ID=10: MySQL基本架构示意图 大体来说,mysql可以分为s ...
- mysql系列-⼀条SQL查询语句是如何执⾏的?
⼀条SQL查询语句是如何执⾏的? ⼤体来说,MySQL 可以分为 Server 层和存储引擎层两部分 Server 层 Server 层包括连接器.查询缓存.分析器.优化器.执⾏器等,涵盖 MySQL ...
- MySQL 笔记整理(2) --日志系统,一条SQL查询语句如何执行
笔记记录自林晓斌(丁奇)老师的<MySQL实战45讲> 2) --日志系统,一条SQL查询语句如何执行 MySQL可以恢复到半个月内任意一秒的状态,它的实现和日志系统有关.上一篇中记录了一 ...
- MySQL 笔记整理(1) --基础架构,一条SQL查询语句如何执行
最近在学习林晓斌(丁奇)老师的<MySQL实战45讲>,受益匪浅,做一些笔记整理一下,帮助学习.如果有小伙伴感兴趣的话推荐原版课程,很不错. 1) --基础架构,一条SQL查询语句如何执行 ...
- 一文读懂一条 SQL 查询语句是如何执行的
2001 年 MySQL 发布 3.23 版本,自此便开始获得广泛应用,随着不断地升级迭代,至今 MySQL 已经走过了 20 个年头. 为了充分发挥 MySQL 的性能并顺利地使用,就必须正确理解其 ...
- mysql数据库系统学习(一)---一条SQL查询语句是如何执行的?
本文基于----MySQL实战45讲(极客时间----林晓斌 )整理----->https://time.geekbang.org/column/article/68319 一.第一节:一条sq ...
- Mysql常用sql语句(3)- select 查询语句基础使用
测试必备的Mysql常用sql语句系列 https://www.cnblogs.com/poloyy/category/1683347.html 前言 针对数据表里面的每条记录,select查询语句叫 ...
- create table 使用select查询语句创建表的方法分享
转自:http://www.maomao365.com/?p=6642 摘要:下文讲述使用select查询语句建立新的数据表的方法分享 ---1 mysql create table `新数据表名` ...
- 20191217-关于JPA @Query查询数据一直为空,直接在数据库里执行SQL则可以查出来
20191217-关于JPA @Query查询数据一直为空,直接在数据库里执行SQL则可以查出来 前提:数据库中查询,由于在视图中无主键概念,只是在代码中由逻辑主键.结果:数据中作为逻辑主键中有个字段 ...
随机推荐
- [Go] gocron源码阅读-go语言中数组和切片的字面值初始化语法
源码中有这么一句,这个函数要求返回的是[]cli.Command,cli.Command类型的切片,这个地方直接使用字面值初始化了一个切片返回去了 return []cli.Command{comma ...
- 渗透测试学习 十、 MSsql注入下
大纲:MySQL介绍及操作 MySQL注入原理 MySQL注入其他操作 一.MySQL介绍及操作 介绍 MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle ...
- Linux:挂载磁盘分区
查看挂载的分区 df 命令主要用来了解系统中已经挂载的各个文件系统的磁盘使用情况. 常用选项: "-h" ,显示更易读的容量单位: "-T" ,显示文件系统的类 ...
- 安全类和远程类shell脚本
批量杀php小马脚本 find /home/hatdot/ -name "*.php" |xargs egrep "phpspy|c99sh|milw0rm|eval\( ...
- Java JDK 运行环境安装
1 Windows系统 1.1 安装包准备 安装包本文档讲解为64位系统,如果是32位系统需要下载32位系统安装包 1.1.1 下载方式 打开jdk官方下载地址,该文档提供jdk版本为1.8 http ...
- golang数据结构和算法之CircularBuffer环形缓冲队列
慢慢练语法和思路, 想说的都在代码及注释里. CircularBuffer package CircularBuffer const arraySize = 10 type CircularBuffe ...
- ACM-后序遍历(简单方法和正规方法)
1.后序遍历简单方法 /**二叉树遍历一般有三种方法:前序,中序,后序.*其中前序遍历u顺序为:根->左子树->右子树,在此定义一种新的遍历方法:根->右子树->左子u树*使用 ...
- 用Python打印九九乘法表与金字塔(*)星号
''' 1*1=1 2*1=2 2*2=4 3*1=3 3*2=6 3*3=9 4*1=4 4*2=8 4*3=12 4*4=16 5*1=5 5*2=10 5*3=15 5*4=20 5*5=25 ...
- C#中Stack集合
Stact<T>集合 特点:后进先出,简单来说就是就是新添加的元素都放到第一位,而且顺序移除元素也是从第一位开始移除. 三个方法: Push(T value);//添加一个值到集合顶部位置 ...
- C读取json格式字符串
python调用C库时参数太多,约定传json格式字符串,C解析 #include<stdio.h> #include<string.h> #include<stdlib ...