我的编程空间,编程开发者的网络收藏夹
学习永远不晚

SQL是如何在数据库中执行的?

短信预约 信息系统项目管理师 报名、考试、查分时间动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码


	SQL是如何在数据库中执行的?


	SQL是如何在数据库中执行的?
[数据库教程]

对很多开发者来说,数据库就是个黑盒子,你会写 SQL,会用数据库,但不知道盒子里面到底是怎么一回事儿,这样你只能机械地去记住别人告诉你的那些优化规则,却不知道为什么要遵循这些规则,也就谈不上灵活运用。

 

数据库的服务端,可以划分为执行器 (Execution Engine) 和存储引擎 (Storage Engine) 两部分。

  • 执行器负责解析 SQL 执行查询
  • 存储引擎负责保存数据。

 

SQL是如何在执行器中执行的 ?

我们通过一个例子来看一下,执行器是如何来解析执行一条 SQL 的。

  • 这个 SQL 语义是,查询用户 ID 大于 50 的用户的所有订单,这是很简单的一个联查,需要查询 users 和 orders 两张表,WHERE 条件就是,用户 ID 大于 50。
技术图片

 

数据库收到查询请求后,需要先解析 SQL 语句,把这一串文本解析成便于程序处理的结构化数据:

  • 转换后的结构化数据,就是一棵树,这个树的名字叫抽象语法树(AST,Abstract Syntax Tree)。上面这个 SQL,它的 AST 大概是这样的:
技术图片

 

这个树太复杂,我只画了主要的部分,你大致看一下,能理解这个 SQL 的语法树长什么样就行了。执行器解析这个 AST 之后,会生成一个逻辑执行计划。所谓的执行计划,可以简单理解为如何一步一步地执行查询和计算,最终得到执行结果的一个分步骤的计划。这个逻辑执行计划是这样的:

技术图片

 

和 SQL、AST 不同的是,这个逻辑执行计划已经很像可以执行的程序代码了。你看上面这个执行计划,很像我们编程语言的函数调用栈,外层的方法调用内层的方法。所以,要理解这个执行计划,得从内往外看。

  1. 最内层的 2 个 LogicalTableScan 的含义是,把 USERS 和 ORDERS 这两个表的数据都读出来。
  2. 然后拿这两个表所有数据做一个 LogicalJoin,JOIN 的条件就是第 0 列 (u.id) 等于第 6 列 (o.user_id)。
  3. 然后再执行一个 LogicalFilter 过滤器,过滤条件是第 0 列 (u.id) 大于 50。
  4. 最后,做一个 LogicalProject 投影,只保留第 0(user_id)、1(user_name)、5(order_id) 三列。这里“投影 (Project)”的意思是,把不需要的列过滤掉。

 

把这个逻辑执行计划翻译成代码,然后按照顺序执行,就可以正确地查询出数据了。但是,按照上面那个执行计划,需要执行 2 个全表扫描,然后再把 2 个表的所有数据做一个 JOIN 操作,这个性能是非常非常差的。

 

优化的总体思路是,在执行计划中,尽早地减少必须处理的数据量。也就是说,尽量在执行计划的最内层减少需要处理的数据量。看一下简单优化后的逻辑执行计划:

技术图片

 

对比原始的逻辑执行计划,这里我们做了两点简单的优化:

  • 尽早地执行投影,去除不需要的列;
  • 尽早地执行数据过滤,去除不需要的行。

 

到这里,执行器只是在逻辑层面分析 SQL,优化查询的执行逻辑,我们执行计划中操作的数据,仍然是表、行和列。在数据库中,表、行、列都是逻辑概念,所以,这个执行计划叫“逻辑执行计划”。执行查询接下来的部分,就需要涉及到数据库的物理存储结构了。

 

转SQL是如何存在存储引擎中执行的?

数据真正存储的时候,无论在磁盘里,还是在内存中,都没法直接存储这种带有行列的二维表。数据库中的二维表,实际上是怎么存储的呢?这就是存储引擎负责解决的问题,存储引擎主要功能就是把逻辑的表行列,用合适的物理存储结构保存到文件中。不同的数据库,它们的物理存储结构是完全不一样的,这也是各种数据库之间巨大性能差距的根本原因。

 

在 InnoDB 中,数据表的物理存储结构是以主键为关键字的 B+ 树,每一行数据直接就保存在 B+ 树的叶子节点上。比如,上面的订单表组织成 B+ 树,是这个样的:

技术图片

 

  • 在 InnoDB 中,表的索引也是以 B+ 树的方式来存储的,和存储数据的 B+ 树的区别是,在索引树中,叶子节点保存的不是行数据,而是行的主键值。
  • 如果通过索引来检索一条记录,需要先后查询索引树和数据树这两棵树:先在索引树中检索到行记录的主键值,然后再用主键值去数据树中去查找这一行数据。

 

优化后的逻辑执行计划将会被转换成物理执行计划,物理执行计划是和数据的物理存储结构相关的。还是用 InnoDB 来举例,直接将逻辑执行计划转换为物理执行计划:

技术图片

 

物理执行计划同样可以根据数据的物理存储结构、是否存在索引以及数据多少等各种因素进行优化。这一块儿的优化规则同样是非常复杂的,比如,我们可以把对用户树的全树扫描再按照主键过滤这两个步骤,优化为对树的范围查找

技术图片

 

最终,按照优化后的物理执行计划,一步一步地去执行查找和计算,就可以得到 SQL 的查询结果了。

 

理解数据库执行 SQL 的过程,以及不同存储引擎中的数据和索引的物理存储结构,对于正确使用和优化 SQL 非常有帮助:

  • 为什么主键不能太长?

因为表的每个索引保存的都是主键的值,过长的主键会导致每一个索引都很大。

  • 有的时候明明有索引却不能命中的原因是?

数据库在对物理执行计划优化的时候,评估发现不走索引,直接全表扫描是更优的选择。

技术图片

SQL是如何在数据库中执行的?

原文地址:https://www.cnblogs.com/ibytecoding/p/13956660.html

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

SQL是如何在数据库中执行的?

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

SQL是如何在数据库中执行的?

对很多开发者来说,数据库就是个黑盒子,你会写 SQL,会用数据库,但不知道盒子里面到底是怎么一回事儿,这样你只能机械地去记住别人告诉你的那些优化规则,却不知道为什么要遵循这些规则,也就谈不上灵活运用。 数据库的服务端,可以划分为执行器 (Execution E

	SQL是如何在数据库中执行的?
2020-12-22

阿里云数据库如何执行SQL

本文将详细介绍阿里云数据库如何执行SQL。阿里云数据库是阿里云提供的一种关系型数据库服务,通过它可以快速地处理大量数据。本文将详细解释如何使用阿里云数据库执行SQL语句。一、准备在执行SQL之前,需要确保已经创建了阿里云数据库,并且已经配置了相应的权限。此外,还需要准备一些数据,用于测试SQL语句。二、执行SQL
阿里云数据库如何执行SQL
2023-10-30

oracle数据库如何执行sql脚本

在 oracle 数据库中,可以使用 sqlplus、oracle enterprise manager 或 pl/sql developer 来执行 sql 脚本。方法如下:1. 使用 sqlplus:加载脚本(@.sql),并执行(en
oracle数据库如何执行sql脚本
2024-05-13

如何在Oracle数据库中执行查询

要在Oracle数据库中执行查询,您可以使用SQL语句。以下是一个简单的示例:SELECT * FROM table_name;在这个查询中,“table_name”是您要查询的表的名称。这将返回表中所有的列和数据。您也可以使用条件来过
如何在Oracle数据库中执行查询
2024-04-09

如何在AmazonAurora中执行跨数据库迁移

在Amazon Aurora中执行跨数据库迁移通常涉及将数据从一个数据库引擎迁移到另一个数据库引擎。以下是在Amazon Aurora中执行跨数据库迁移的一般步骤:创建目标数据库:首先,在Amazon Aurora中创建一个新的数据库实例,
如何在AmazonAurora中执行跨数据库迁移
2024-04-09

如何在Oracle中执行跨数据库查询

在Oracle中执行跨数据库查询可以通过数据库链接(Database Link)来实现。以下是实现步骤:创建数据库链接:在目标数据库中创建一个到源数据库的数据库链接,可以使用以下SQL语句创建数据库链接:CREATE DATABASE L
如何在Oracle中执行跨数据库查询
2024-04-09

如何在Oracle数据库中执行跨表查询

在Oracle数据库中执行跨表查询通常使用SQL语句中的JOIN操作符。以下是一些常用的跨表查询示例:内连接(INNER JOIN):返回两个表之间共有的行。SELECT table1.column1, table2.column2FRO
如何在Oracle数据库中执行跨表查询
2024-03-02

在Oracle中如何执行数据库升级和迁移

在Oracle数据库中,执行数据库升级和迁移通常涉及以下步骤:创建数据库备份:在进行升级或迁移之前,首先应该创建数据库的完整备份,以防止数据丢失或损坏。升级数据库软件:如果需要升级数据库软件版本,应该按照Oracle官方文档提供的步骤进行操
在Oracle中如何执行数据库升级和迁移
2024-04-09

如何在mysql中执行sql脚本

这篇文章给大家介绍如何在mysql中执行sql脚本,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。第一种方法:在命令行下(未连接数据库)输入 mysql -h localhost -u root -p123456 < F
2023-06-14

使用Java如何将SQL脚本文件执行到数据库中

使用Java如何将SQL脚本文件执行到数据库中?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。方式一:直接读取SQL脚本文件的内容,然后传递到SQL中。代码:RunSqlSe
2023-05-31

SQL SERVER 下,批量在不同的数据库中执行相同的脚本

转自:https://blog.51cto.com/liuxinya/354983 作为DBA我们经常需要对不同的数据库执行相同的查询,如果你的服务器上只有2个数据库当然可以手工依次执行,但如果一个数据库服务器上有几百个库呢,你是否觉得会崩溃呢。 解决方法:

	SQL SERVER 下,批量在不同的数据库中执行相同的脚本
2018-06-20

如何使用JDBC连接数据库并执行SQL语句

JDBC是Java数据库连接的缩写,是Java程序与数据库进行交互的标准API。JDBC主要包括Java.sql和javax.sql两个包,通过DriverManager获取数据库连接对象Connection,并通过Statement或PreparedStatement执行SQL语句
2023-05-18

PHP数据库学习之如何使用PDO执行SQL语句

这篇文章主要讲解了“PHP数据库学习之如何使用PDO执行SQL语句”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“PHP数据库学习之如何使用PDO执行SQL语句”吧!exec() 方法在我们执
2023-06-25

如何在SQLServer中执行动态SQL语句

在SQL Server 中执行动态 SQL 语句通常可以通过以下几种方式实现:使用 sp_executesql 存储过程:sp_executesql 是 SQL Server 提供的一个用于执行动态 SQL 语句的存储过程。通过将动态 SQ
如何在SQLServer中执行动态SQL语句
2024-04-09

编程热搜

目录