两个案例带你看懂 YashanDB 执行计划

简介: 两个案例带你看懂 YashanDB 执行计划

执行计划是数据库查询优化的基石。学习阅读执行计划有助于深入了解数据库对 SQL 查询的解析和执行机制。执行计划揭示了查询的逻辑流程,包括表连接方式、数据过滤和聚合方法以及结果排序规则,这对于诊断性能瓶颈、优化查询速度和提高资源利用率至关重要。开发人员可以通过分析执行计划,识别索引使用的有效性,确定是否需要调整查询结构,以及是否需要更新数据库统计信息,从而编写更高效的 SQL 代码,提升数据库性能,确保数据检索兼具速率与成本效益。

简而言之,学习阅读执行计划是每个数据库开发者和管理员必备的技能。在本文中,将会基于 YashanDB 已发布版本,详细展开 YashanDB 执行计划的阅读方式。

在接下来的所有演示中,我们将基于如下的建表语句进行:

对于以上的两张表,我们将使用两个较为简单的查询语句用作范例,其中一个包含子查询信息,另一个不包含,为大家详细讲解如何阅读执行计划。

查看 YashanDB 计划的方法很简单,在对应需要查看执行计划的语句开头加入 explain 关键字,服务端即可返回执行计划并在客户端打印。

通过这种方式将上述语句打印后可以得到如下图的执行计划:

图片

按照图 1 中所示,我们将分为三部分阅读打印出来的信息。

第一行 SQL hash value 表示的是当前输入的 SQL 文本的唯一标识,在一些计划或 SQL 语句相关的视图中可以直接通过这个值找到这条 SQL 语句。

第二行 Optimizer 表示的是优化当前语句执行计划所选用的优化器,ADOPT_C 表示的是基于代价的优化器(Cost Base Optimizer)。在 YashanDB 于 22.2 版本正式上线 CBO 之后,所有的计划优化都由 CBO 进行,不存在其它优化方式。

图片

YashanDB 的计划树部分按照表格的形式进行打印,共七列,其从左到右包含的信息分别是:

Id: 算子序号,是该算子在整个计划树中的唯一标识。

Operation type: 算子名称。

Name: 当前算子操作的存储对象名称,一般是表名 / 视图名 / 索引名等。

Owner: 当前算子操作对象所属的用户。

Rows: 当前算子执行的条数,该数据为优化器根据语句综合当前统计信息所预估的。

Cost: 计划树执行到当前算子所需的代价(总时长)。

Partition info: 当计划树中有对分区表的操作时,将会在这一列显式分区的扫描方案。

YashanDB 的计划是按照树形结构来进行连接的,整体对外的形式则是一颗多叉树,执行方式是从根节点开始的先深度后广度的后序遍历。

树形结构的父节点与子节点则是通过缩进来表示,处于同一缩进等级下的算子表示拥有相同的父节点,图中序号 3 和 4 的算子缩进相同,是序号 2 哈希连接的子节点。

对于不同的连接方式来说,上下两个孩子的含义也不相同,YashanDB 当前支持哈希(Hash)连接,嵌套循环(Nested Loop)连接还有归并(Merge)连接,哈希连接中上方子节点是探查表(Probe),下方子节点是构建表(Build);而对于嵌套循环连接和归并连接来说,上方是左表,下方表示右表。

最后一部分则是最下方标题为 Operation Information 的部分,该部分在不打开额外开关的情况下显示的是对应序号算子所包含的谓词信息、分组信息等。在这里重点介绍的则是 filter(过滤谓词)和 access(访问谓词)两个信息。

图片

图片

根据上面的执行流程,我们可以较为简单地认为 access 与 filter 的区别如下:

某个算子上可能会同时出现 access 与 filter 两种谓词;

access(访问谓词):是在某个算子从前一层获取数据时提前处理数据的谓词。用于数据被选出之前的检索,可减少不必要的数据传输和处理,提高效率;

filter(过滤谓词):当某个算子获取到数据进入自身缓存区时,再检查数据是否满足条件的谓词。用于数据选出后的重新过滤,能进行更精细的筛选。

数据库的表连接操作可以认为是从两个表中各取出一条数据,将其拼接在一起。当表连接过程中有访问谓词,如图 1 中序号为 2 为例,T1.ID = T2.ID,可以近似地认为在数据连接之前,扫描的过程中就判断这两条数据是否满足了连接条件;而不是像嵌套循环连接那样,先将两边的数据拼合起来,再判断这条数据是否满足过滤条件。

总之,哈希连接通过提前使用访问谓词进行判断,可以避免不必要的数据拼合操作,提高连接操作的效率。

至此为止,我们计划上的一些基本信息就已经说明完了。

我们上面讲到的例子都是不包含子查询的语句,而子查询同样也是查询时出现频率非常高的语法成分。我们先看以下的语句:

图片

在拿到含子查询的执行计划时,首先界定子查询计划范围。图中 Name 栏序号 1 的算子被标记为 QUEYR [1],在 YashanDB 中主查询的查询序号为 0,因此 QUERY [1] 算子即为子查询起始,到下一个同缩进算子(即序号 3 的 SORT GROUP)为止,即 1-2 号算子属于 QUERY [1] 的范围。此外下方算子信息中的 QUERY [1],表示它将会在序号为 6 的 TABLE ACCESS FULL 上被执行。

另外可能也有小伙伴们会对图 2 中的索引扫描方式感兴趣,在这里也稍微介绍一下 YashanDB 常见的扫描方式。

TABLE ACCESS FULL: 全表扫描,将表中数据全部扫描,不包含访问谓词。

INDEX ACCESS FULL: 全索引扫描,与全表扫描类似,扫描的对象变为索引,不包含访问谓词。

INDEX FAST FULL SCAN: 快速索引扫描,根据索引物理块相连进行扫描,返回数据无序,不包含访问谓词。

INDEX UNIQUE SCAN: 索引唯一值扫描,当索引为主键索引或唯一索引且访问条件为等值条件时,可以直接在索引上查询对应的位置,实现单点查询并返回。

INDEX RANGE SCAN: 索引范围查询,根据索引的有序性,只扫描满足条件的某一段范围内的数据,搭配访问谓词使用。

INDEX SCAN MIN/MAX: 索引最大 / 最小值扫描,YashanDB 的普通索引按照 B 树形式进行构建,当在聚合查询需要查询最大或最小值时,可以直接访问索引的头节点或尾节点以直接得到该列的最大或最小值。

INDEX SKIP SCAN: 索引跳跃扫描,索引扫描中较为复杂的一种,下面结合场景进行说明。当有一个学校成员的表格,其中记录了某个学校里所有学生的信息,包括性别,年龄,年级,入学考试总分等,该表有且仅有一个索引 index1,其建立在性别与入学考试总分这两项上。当 DBA 想查询入学考试总分在 500 - 600 分区间的所有学生列表时,按照索引结构来说,并不能直接使用 index1 来进行过滤,此时我们可以直接跳过 index1 的性别这一列,在性别这一列的每一个取值上,做一个 500 < 总分 < 600 的过滤。即在性别为男与性别为女这两个子树上分别做 500 < 总分 < 600 的过滤。

TABLE ACCESS BY INDEX ROWID: 回表操作,严格来说属于任意索引扫描的一部分,当索引所能提供的列不完全满足上方算子要求时,索引需要根据自身 ROWID 信息,回到表中重新取得缺失的列数据,由于会产生更多的额外 IO 操作,因此在数据库应用中应当避免大数据量的回表。

在数据库调优的过程中,索引的建立与选择是对数据库性能影响大的环节,适合的索引与适合的索引扫描方式往往能带来性能上的质的提升。因此,数据库调优过程中需要平衡索引的使用,确保索引的创建和维护对性能的提升大于其带来的开销。正确的索引策略需要基于对查询模式、数据访问模式和业务需求的深入理解。

投影信息为 YashanDB 计划打印的拓展功能。投影指的是上层算子从表或下方算子的结果集中选择特定的列(字段)来形成一个结果集,而不需要包括其他列。其使用方法为:在待打印的查询语句前加入如下关键字 EXPLAIN PLAN SET PROJ ON FOR。

对例 1 的语句打开投影打印后可以得到如图 5 所展示的计划。

图片

在图中我们可以看到,正常情况下,两张两列的表进行连接后的结果应该是 4 列,而此处序号为 2 的哈希连接,其 projection 信息仅有 T1.SCORE 与 T2.NAME 两列,这是由于上层分组算子仅使用了这两列进行运算,因此传递给下层算子的需求也仅仅只是这两列。

这种投影优化后,可以看到 join 实际只需提供两列,当表列很多但实际用列较少时,上层算子无需在内存中记录不需要的表达式,可节省大量内存空间。

以上的这些也只是一些 YashanDB 中在计划打印里比较常出现的成分的说明,YashanDB 所提供的算子与信息显示还有很多的可以讲或者可以了解的地方,更多的信息欢迎到崖山官网文档中心(https://doc.yashandb.com)进行查阅。

相关文章
|
开发框架 Java Linux
GeoServe Web 管理界面 远程访问
下面介绍GeoServer web ui 管理界面 结合cpolar 内网穿透工具实现远程访问
336 2
GeoServe Web 管理界面 远程访问
|
缓存 网络协议 Linux
手把手实现tcp/ip用户态协议栈,帮你实践网络知识(网络必备,面试项目)
手把手实现tcp/ip用户态协议栈,帮你实践网络知识(网络必备,面试项目)
|
9月前
|
自然语言处理 算法 JavaScript
面向长文本的多模型协作摘要架构:多LLM文本摘要方法
多LLM摘要框架通过生成和评估两个步骤处理长文档,支持集中式和分散式两种策略。每个LLM独立生成文本摘要,集中式方法由单一LLM评估并选择最佳摘要,而分散式方法则由多个LLM共同评估,达成共识。论文提出两阶段流程:先分块摘要,再汇总生成最终摘要。实验结果显示,多LLM框架显著优于单LLM基准,性能提升最高达3倍,且仅需少量LLM和一轮生成评估即可获得显著效果。
283 10
面向长文本的多模型协作摘要架构:多LLM文本摘要方法
|
12月前
|
存储 Java 数据库
事务的四大特性及其实现原理:深入剖析与实战示例
【10月更文挑战第17天】在数据库管理和分布式系统设计中,事务(Transaction)扮演着至关重要的角色。事务的四大特性——原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability),通常简称为ACID特性。
551 1
|
网络协议 算法 安全
HTTP/2 协议-Stream 的状态变迁
HTTP/2 协议-Stream 的状态变迁
491 0
|
Linux 应用服务中间件 nginx
内网环境下 - 安装linux命令、搭建docker以及安装镜像
内网环境docker镜像的安装,以及内网环境如何安装linux命令
2094 3
内网环境下 - 安装linux命令、搭建docker以及安装镜像
|
网络协议 Linux 数据安全/隐私保护
本地电脑搭建SFTP服务器,并实现公网访问
本地电脑搭建SFTP服务器,并实现公网访问
1197 0
|
SQL 存储 前端开发
AnalyticDB MySQL--读懂执行计划
本文是AnalyticDB MySQL的学习笔记,描述了sql的执行过程,执行计划的基本概念,以及怎样解释执行计划
788 0
AnalyticDB MySQL--读懂执行计划
|
网络协议 关系型数据库 MySQL
搭建邮件服务器和论坛
今天一起来看看如何搭建自己的邮件服务器和论坛服务,使用的工具分别为 Ewomail 和 Discourse。
搭建邮件服务器和论坛