限时领|《AI 百问百答》专栏课+实体书(包邮)! 了解详情
写点什么

学会用数据库的方式思考 SQL 是如何执行的

  • 2019-07-02
  • 本文字数:3537 字

    阅读完需:约 12 分钟

学会用数据库的方式思考SQL是如何执行的

虽然 SQL 是声明式语言,我们可以像使用英语一样使用它,不过在 RDBMS(关系型数据库管理系统)中,SQL 的实现方式还是有差别的。今天我们就从数据库的角度来思考一下 SQL 是如何被执行的。


关于今天的内容,你会从以下几个方面进行学习:


  1. Oracle 中的 SQL 是如何执行的,什么是硬解析和软解析;

  2. MySQL 中的 SQL 是如何执行的,MySQL 的体系结构又是怎样的;

  3. 什么是存储引擎,MySQL 的存储引擎都有哪些?

Oracle 中的 SQL 是如何执行的

我们先来看下 SQL 在 Oracle 中的执行过程:



从上面这张图中可以看出,SQL 语句在 Oracle 中经历了以下的几个步骤。


  1. 语法检查:检查 SQL 拼写是否正确,如果不正确,Oracle 会报语法错误。

  2. 语义检查:检查 SQL 中的访问对象是否存在。比如我们在写 SELECT 语句的时候,列名写错了,系统就会提示错误。语法检查和语义检查的作用是保证 SQL 语句没有错误。

  3. 权限检查:看用户是否具备访问该数据的权限。

  4. 共享池检查:共享池(Shared Pool)是一块内存池,最主要的作用是缓存 SQL 语句和该语句的执行计划。Oracle 通过检查共享池是否存在 SQL 语句的执行计划,来判断进行软解析,还是硬解析。那软解析和硬解析又该怎么理解呢?

  5. 在共享池中,Oracle 首先对 SQL 语句进行 Hash 运算,然后根据 Hash 值在库缓存(Library Cache)中查找,如果存在 SQL 语句的执行计划,就直接拿来执行,直接进入“执行器”的环节,这就是软解析。

  6. 如果没有找到 SQL 语句和执行计划,Oracle 就需要创建解析树进行解析,生成执行计划,进入“优化器”这个步骤,这就是硬解析。

  7. 优化器:优化器中就是要进行硬解析,也就是决定怎么做,比如创建解析树,生成执行计划。

  8. 执行器:当有了解析树和执行计划之后,就知道了 SQL 该怎么被执行,这样就可以在执行器中执行语句了。


共享池是 Oracle 中的术语,包括了库缓存,数据字典缓冲区等。我们上面已经讲到了库缓存区,它主要缓存 SQL 语句和执行计划。而数据字典缓冲区存储的是 Oracle 中的对象定义,比如表、视图、索引等对象。当对 SQL 语句进行解析的时候,如果需要相关的数据,会从数据字典缓冲区中提取。


库缓存这一个步骤,决定了 SQL 语句是否需要进行硬解析。为了提升 SQL 的执行效率,我们应该尽量避免硬解析,因为在 SQL 的执行过程中,创建解析树,生成执行计划是很消耗资源的。


你可能会问,如何避免硬解析,尽量使用软解析呢?在 Oracle 中,绑定变量是它的一大特色。绑定变量就是在 SQL 语句中使用变量,通过不同的变量取值来改变 SQL 的执行结果。这样做的好处是能提升软解析的可能性,不足之处在于可能会导致生成的执行计划不够优化,因此是否需要绑定变量还需要视情况而定。


举个例子,我们可以使用下面的查询语句:


SQL> select * from player where player_id = 10001;
复制代码


你也可以使用绑定变量,如:


SQL> select * from player where player_id = :player_id;
复制代码


这两个查询语句的效率在 Oracle 中是完全不同的。如果你在查询 player_id = 10001 之后,还会查询 10002、10003 之类的数据,那么每一次查询都会创建一个新的查询解析。而第二种方式使用了绑定变量,那么在第一次查询之后,在共享池中就会存在这类查询的执行计划,也就是软解析。


因此我们可以通过使用绑定变量来减少硬解析,减少 Oracle 的解析工作量。但是这种方式也有缺点,使用动态 SQL 的方式,因为参数不同,会导致 SQL 的执行效率不同,同时 SQL 优化也会比较困难。

MySQL 中的 SQL 是如何执行的

Oracle 中采用了共享池来判断 SQL 语句是否存在缓存和执行计划,通过这一步骤我们可以知道应该采用硬解析还是软解析。那么在 MySQL 中,SQL 是如何被执行的呢?


首先 MySQL 是典型的 C/S 架构,即 Client/Server 架构,服务器端程序使用的 mysqld。整体的 MySQL 流程如下图所示:



你能看到 MySQL 由三层组成:


  1. 连接层:客户端和服务器端建立连接,客户端发送 SQL 至服务器端;

  2. SQL 层:对 SQL 语句进行查询处理;

  3. 存储引擎层:与数据库文件打交道,负责数据的存储和读取。


其中 SQL 层与数据库文件的存储方式无关,我们来看下 SQL 层的结构:



  1. 查询缓存:Server 如果在查询缓存中发现了这条 SQL 语句,就会直接将结果返回给客户端;如果没有,就进入到解析器阶段。需要说明的是,因为查询缓存往往效率不高,所以在 MySQL8.0 之后就抛弃了这个功能。

  2. 解析器:在解析器中对 SQL 语句进行语法分析、语义分析。

  3. 优化器:在优化器中会确定 SQL 语句的执行路径,比如是根据全表检索,还是根据索引来检索等。

  4. 执行器:在执行之前需要判断该用户是否具备权限,如果具备权限就执行 SQL 查询并返回结果。在 MySQL8.0 以下的版本,如果设置了查询缓存,这时会将查询结果进行缓存。


你能看到 SQL 语句在 MySQL 中的流程是:SQL 语句→缓存查询→解析器→优化器→执行器。在一部分中,MySQL 和 Oracle 执行 SQL 的原理是一样的。


与 Oracle 不同的是,MySQL 的存储引擎采用了插件的形式,每个存储引擎都面向一种特定的数据库应用环境。同时开源的 MySQL 还允许开发人员设置自己的存储引擎,下面是一些常见的存储引擎:


  1. InnoDB 存储引擎:它是 MySQL 5.5 版本之后默认的存储引擎,最大的特点是支持事务、行级锁定、外键约束等。

  2. MyISAM 存储引擎:在 MySQL 5.5 版本之前是默认的存储引擎,不支持事务,也不支持外键,最大的特点是速度快,占用资源少。

  3. Memory 存储引擎:使用系统内存作为存储介质,以便得到更快的响应速度。不过如果 mysqld 进程崩溃,则会导致所有的数据丢失,因此我们只有当数据是临时的情况下才使用 Memory 存储引擎。

  4. NDB 存储引擎:也叫做 NDB Cluster 存储引擎,主要用于 MySQL Cluster 分布式集群环境,类似于 Oracle 的 RAC 集群。

  5. Archive 存储引擎:它有很好的压缩机制,用于文件归档,在请求写入时会进行压缩,所以也经常用来做仓库。


需要注意的是,数据库的设计在于表的设计,而在 MySQL 中每个表的设计都可以采用不同的存储引擎,我们可以根据实际的数据处理需要来选择存储引擎,这也是 MySQL 的强大之处。

数据库管理系统也是一种软件

我们刚才了解了 SQL 语句在 Oracle 和 MySQL 中的执行流程,实际上完整的 Oracle 和 MySQL 结构图要复杂得多:




如果你只是简单地把 MySQL 和 Oracle 看成数据库管理系统软件,从外部看难免会觉得“晦涩难懂”,毕竟组织结构太多了。我们在学习的时候,还需要具备抽象的能力,抓取最核心的部分:SQL 的执行原理。因为不同的 DBMS 的 SQL 的执行原理是相通的,只是在不同的软件中,各有各的实现路径。


既然一条 SQL 语句会经历不同的模块,那我们就来看下,在不同的模块中,SQL 执行所使用的资源(时间)是怎样的。下面我来教你如何在 MySQL 中对一条 SQL 语句的执行时间进行分析。


首先我们需要看下 profiling 是否开启,开启它可以让 MySQL 收集在 SQL 执行时所使用的资源情况,命令如下:


mysql> select @@profiling;
复制代码


profiling=0 代表关闭,我们需要把 profiling 打开,即设置为 1:


mysql> set profiling=1;
复制代码


然后我们执行一个 SQL 查询(你可以执行任何一个 SQL 查询):


mysql> select * from wucai.heros;
复制代码


查看当前会话所产生的所有 profiles:



你会发现我们刚才执行了两次查询,Query ID 分别为 1 和 2。如果我们想要获取上一次查询的执行时间,可以使用:


mysql> show profile;
复制代码



当然你也可以查询指定的 Query ID,比如:


mysql> show profile for query 2;
复制代码


查询 SQL 的执行时间结果和上面是一样的。


在 8.0 版本之后,MySQL 不再支持缓存的查询,原因我在上文已经说过。一旦数据表有更新,缓存都将清空,因此只有数据表是静态的时候,或者数据表很少发生变化时,使用缓存查询才有价值,否则如果数据表经常更新,反而增加了 SQL 的查询时间。


你可以使用 select version()来查看 MySQL 的版本情况。


总结

我们在使用 SQL 的时候,往往只见树木,不见森林,不会注意到它在各种数据库软件中是如何执行的,今天我们从全貌的角度来理解这个问题。你能看到不同的 RDBMS 之间有相同的地方,也有不同的地方。


相同的地方在于 Oracle 和 MySQL 都是通过解析器→优化器→执行器这样的流程来执行 SQL 的。


但 Oracle 和 MySQL 在进行 SQL 的查询上面有软件实现层面的差异。Oracle 提出了共享池的概念,通过共享池来判断是进行软解析,还是硬解析。而在 MySQL 中,8.0 以后的版本不再支持查询缓存,而是直接执行解析器→优化器→执行器的流程,这一点从 MySQL 中的 show profile 里也能看到。同时 MySQL 的一大特色就是提供了各种存储引擎以供选择,不同的存储引擎有各自的使用场景,我们可以针对每张表选择适合的存储引擎。



内容来自极客时间专栏《SQL必知必会》,作者陈旸,清华大学计算机博士,如果这篇文章帮你理顺了 Oracle 和 MySQL 执行 SQL 的过程,欢迎你把它分享给你的朋友或者同事。


2019-07-02 17:0713546

评论 2 条评论

发布
用户头像
大数据的SQL优化,也可以借鉴
2019-07-07 18:25
回复
用户头像
确定mysql 8.0之后没有执行计划的缓存?
2019-07-03 22:56
回复
没有更多了
发现更多内容

MySQL派生表查询大数据量无结果问题分析与解决

GreatSQL

Selenium — Playwright 自动化测试框架

测试人

时序数据库 TDengine × Power BI:高频数据也能秒级响应

TDengine

数据库 tdengine 时序数据库

二级等保

等保测评

VKProxy新增速率限制功能

八苦-瞿昙

黑龙江腾讯云:科技赋能,助力龙江新发展

等保测评

仅32B,昆仑万维开源「自主代码智能体模型Skywork-SWE-32B」,拿下代码开源SOTA

新消费日报

Redis 是单线程模型?|得物技术

得物技术

html 前端 Bootstrap Studio mac

AI阅读APP的核心功能

北京木奇移动技术有限公司

软件外包公司 AI英语学习 AI阅读

时序数据库 TDengine x Kepware:解决你最头疼的“设备接入”问题

TDengine

数据库 tdengine 时序数据库

企业放弃TeamViewer转投贝锐向日葵企业版:性能价格向日葵均有优势

科技热闻

如何测试DNS解析状态是否正常?

国科云

鸿蒙运动项目开发:封装超级好用的 RCP 网络库(下)—— 实战应用

王二蛋和他的张大花

智慧园区系统(源码+文档+讲解+演示)

深圳亥时科技

从API测试看企业系统性落地AI的鸿沟

思码逸研发效能

研发效能 智能测试 API 测试 研发效能管理 思码逸

1688商品列表API接口全解析:从关键词搜索到分页处理方案

tbapi

1688商品列表接口 关键词搜索1688商品接口 1688API 1688数据采集

别划走!选择无代码平台的10个理由!

积木链小链

数字化转型 无代码 无代码平台

跨境卖家必看!2025年1688API新功能解锁全球供应链

tbapi

1688商品详情接口 1688商品列表接口 1688API 1688寻源通API

什么是数字化创新?数字化创新能给企业带来什么好处?

优秀

数字化 数字化创新 数字化赋能升级

时序数据库 TDengine 助力华锐 D5 平台实现“三连降”:查询快了,机器少了,成本也低了

TDengine

数据库 tdengine 时序数据库

大数据-17 Flume 分布式日志收集 实时采集引擎 Source Channel Sink 串行复制负载均衡

武子康

大数据 hadoop flume

AI进行时,AlphaGPT引领法律服务新时代

科技汇

发扬数字人文!山东大学发布边疆大模型,清华指导AI通识教育白皮书

ModelWhale

清华 山东大学 人工智能教育

时序数据库 TDengine 通过麒麟全系列兼容性认证,稳了!

TDengine

数据库 tdengine 时序数据库

AI教育APP的开发

北京木奇移动技术有限公司

AI教育 软件外包公司 AI英语学习

合合信息发布业内首个AI Agent跨平台云资源智能管理终端

合合技术团队

人工智能 大数据 算法

《HarmonyOSNext教育应用性能飞跃:ArkTS长列表优化5大实战指南》

Turing_010

《HarmonyOSNext性能飞跃秘籍:响应优化0.1秒生死线必备指南》

Turing_010

短短一年,是什么让移动AI颠覆想象?

脑极体

AI

项目管理利器:甘特图的全面解析与应用指南

敏捷开发

甘特图 #项目管理

利用 Amazon Bedrock 构建高效 SEO 内容生成系统:从流量挖掘到智能创作

亚马逊云科技 (Amazon Web Services)

学会用数据库的方式思考SQL是如何执行的_数据库_陈旸_InfoQ精选文章