AntDB-T提升查询性能的关键之查询优化解析

news2024/11/25 12:41:17

查询优化器是提升查询效率非常重要的手段,本文将主要介绍AntDB-T数据库查询优化的相关设计。AntDB-T数据库是一款企业级通用分布式关系型数据库,而查询是AntDB-T数据库管理系统中最关键、最吸引人的功能之一。每个生产数据库系统每天都需要处理大量的查询,为了使这些查询运行得更快、更好,AntDB-T数据库管理系统的查询优化器中融入了大量的优化技术。这些优化技术是众多研究者和技术人员数十年来的精华总结。

AntDB-T查询优化原理

(一)AntDB-T查询优化是什么

查询优化是数据库管理系统中的一个关键模块,如图 1 所示,橙色模块为查询优化所处的位置,当一条SQL进来之后,可以看到会经过Parser → Analyzer → Rewriter → Planner → Executor这一系列步骤:

1.SQL进行Parser处理,它会对SQL进行语法分析并生成语法解析树。

2.SQL进行Analyzer处理,它主要对SQL进行语义分析并生成查询树。

3.若SQL是DDL语句且是非分布式时的无需进行优化若SQL是DDL语句且是分布式时需要针对某些场景做特殊处理。

4.满足步骤3条件的到Executor进行处理,并结束。不满足步骤3条件的,即对于SQL是DML则需要按照完整的流程进行处理。

5.SQL进入到Rewriter进行查询重写处理。

6.SQL进入到Planner并对其进行逻辑等价变换和物理执行路径筛选,最终选择最优的执行路径,生成执行计划。简单来说,查询优化器输入的是查询树,输出的是查询执行计划。

7.将步骤6产生的执行计划传递给Executor数据库执行器模块,并结束。

图片

图1:SQL的执行过程

AntDB-T数据库的查询优化方法分为两个层次:

1)基于规则的查询优化(逻辑优化, Rule Based Optimization ,简称 RBO )。

2)基于代价的查询优化 (物理优化,Cost Based Optimization,简称 BO )。

逻辑优化是建立在关系代数基础上的优化,关系代数中有一些等价的逻辑变换规则,通过对关系代数表达式进行逻辑上的等价变换,可能会获得执行性能比较好的等式,这样就能提高查询的性能。

而物理优化则是在建立物理执行路径的过程中进行优化,关系代数中虽然指定了两个关系如何进行连接操作,但是这时的连接操作符属于逻辑运算符,它没有指定以何种方式实现这种逻辑连接操作,而查询执行器是不“认识”关系代数中的逻辑连接操作的,我们需要生成多个物理连接路径来实现关系代数中的逻辑连接操作,并且根据查询执行器的执行步骤,建立代价计算模型,通过计算所有的物理连接路径的代价,从中选择出“最优”的路径。

(二)AntDB-T为什么要引入查询优化

一般数据库的使用者在书写 SQL 语句的时候也经常会考虑到查询的性能,但是一个应用程序可能要写大量的SQL 语句,而有些 SQL语句的逻辑极为复杂,数据库应用开发人员很难面面俱到地写出“极好的”语句,而AntDB-T查询优化相对于数据库应用开发人员而言,具有一些独特的优势,比如:AntDB-T查询优化在优化的过程中会参考数据库统计模块自动产生的统计信息、查询优化器和数据库用户之间的计算能力不同等。

AntDB-T查询优化是一项至关重要的功能,其职责是生成最理想的查询执行计划。AntDB-T查询优化可以提高数据库查询的性能和响应时间;提升用户体验;识别和优化复杂的查询,使查询更容易理解和维护。此外,还可以改进查询性能,减少系统资源的使用,提高系统的可用性和可扩展性。

AntDB-T查询优化实现方式

(一)AntDB-T查询优化实现路径

AntDB-T数据库的查询优化方法分为逻辑优化和物理优化,如图 2所示。

图片

图2:查询优化的方法

1.逻辑优化

逻辑优化分为逻辑重写优化和逻辑分解优化。

(1)逻辑重写优化

在逻辑重写优化阶段主要还是对查询树进行“重写”,也就是说在查询树上进行改造,改造之后还是颗查询树,而在逻辑分解阶段,会将查询树打散,重新建立等价于查询树的逻辑关系。逻辑重写优化主要包含子查询提升、Union all 优化、展开继承表、预处理表达式、外连接消除等等。

(2)逻辑分解优化

而逻辑分解优化是逻辑优化的一部分,主要开始和物理优化产生了紧密的联系。在逻辑分解阶段则将约束条件(查询树里面的裸表达式)用RestrictInfo结构体来进行封装,这样就可以扩展表达式的内容,比如在RestrictInfo结构体中还记录了约束条件在物理优化过程中需要的变量。在查询树(Query)中,约束条件(表达式)存放的位置就是它原始的语法位置,在逻辑分解的过程中,会对这些约束条件尝试下推,RestrictInfo结构体的出现也是为了在下推的时候能够更好地和RelOptInfo结构体结合。逻辑分解优化主要包含谓词下推、消除无用连接项、Semi join消除等等。

2.物理优化

那物理优化是什么呢?简单说就是对于一条SQL,数据库可以有多种方式去执行,条条大路通罗马,比如顺序扫描、索引扫描,多表连接的话又有nestloop、hashjoin、mergejoin等,举个通俗的例子,我要从杭州出差去北京,我可以选择坐飞机,也可以坐高铁,也可以坐轮船,甚至可以骑车去也行,无外乎效率(money)的问题,AntDB-T数据库也是如此,需要有一种机制告诉它如何去选择一条最优的方式去生成执行计划,这就是物理优化。物理优化主要包含表的扫描方式选择、表的join方式、表join的顺序等等。

(二)AntDB-T查询优化实现方式

下面将针对查询优化进行代码简要说明。本次以AntDB-T的代码为例,来解析查询优化的实现方式。

1.AntDB-T数据库查询优化模块的主入口函数是planner函数。这个函数会检查当前库是否定义了自定义的优化方法(planner_hook)。如果没有自定义的优化方法(即planner_hook为空),那么就会调用standard_planner函数如图3所示,这是AntDB-T数据库查询优化的标准函数。

图片

图3:查询优化的主入口函数

2.standard_planner函数中又包含了许多重要的函数如下图4所示,其中subquery_planner是查询优化主要实现函数。

3.subquery_planner函数下面的grouping_planner函数之前的部分属于逻辑重写优化,而grouping_planner函数中的一部分属于逻辑分解优化,另一部分则是属于物理优化。

4.调用完函数subquery_planner后,会调用 fetch_upper_rel、get_cheapest_fractional_path获取到经过物理优化生成的最优的路径。

5.调用create_plan函数转换成执行计划。

6.调用SS_finalize_plan函数,它会对这个执行计划中的Param节点进行最后的处理。

经过这一系列步骤之后,最终产生了执行计划,这个执行计划会被传递给查询执行模块进行SQL的执行操作。

图片

图4:查询优化函数调用图

为便于更好地了解查询优化预处理表达式中的常量化简这一优化方法,下面以具体的SQL为例展开分析:

首先是建表,接着构造数据,然后建立索引,再收集统计信息,如下图5所示:

图片

图5:构造数据

最后查看带有常量表达式的SQL的执行计划,如下图6所示:

图片

图6:常量化简的执行计划

可以看到,在此例中,AntDB-T数据库将谓词id = 8 + 9转化成了 id = 17,这样SQL语句就可以使用索引扫描,这种扫描方法提高了扫描表的效率;而原来优化前使用的是顺序扫描。这便是常量化简这一查询优化的原理。

常量化简这个优化代码的实现在preprocess_expression->eval_const_expressions 这个函数中实现,这个函数递归调用了

eval_const_expressions_mutator函数, eval_const_expressions_mutator函数针对不同的表达式比如函数表达式、操作符表达式、布尔表达式等分别做不同的优化处理。

此例中id = 8 + 9转成id = 17这个步骤主要是调用eval_const_expressions_mutator->simplify_function-> evaluate_function函数来实现的,通过调用evaluate_function-> evaluate_expr函数执行8+9 这个操作 得出结果是17。

常量化简的主要的优化点有参数常量化、函数常量化、约束条件常量化3个方面,参数的常量化是通过遍历参数的表达式实现的,如果发现参数表达式中全部为常量,则对参数执行预先求值。

(三)AntDB-T查询计划评估

前面介绍了查询优化是怎么实现的,下面来看看如何查看生成好的执行计划。

在AntDB-T数据库中查看执行计划使用Explain命令,Explain命令显示每个给定的DML语句选中的执行计划的预计开销,使用Explain 命令时,ANALYZE 选项将导致语句的执行,也将会显示实际执行时间。生成的执行计划阅读方式是自下而上的,每行信息代表一个节点。

1.Explain命令语法:

Explain命令的语法如下:

EXPLAIN [ ( option [, ...] ) ] statement

EXPLAIN [ ANALYZE ] [ VERBOSE ] statement

这里option可选项如下:

  •     ANALYZE [ boolean ]

  •     VERBOSE [ boolean ]

  •     COSTS [ boolean ]

  •     SETTINGS [ boolean ]

  •     BUFFERS [ boolean ]

  •     WAL [ boolean ]

  •     TIMING [ boolean ]

  •     SUMMARY [ boolean ]

  •    FORMAT { TEXT | XML | JSON | YAML }

可选项的含义:

  • ANALYZE:真正执行实际的SQL,会修改数据库结构,可以把EXPLAIN ANALYZE放到事务中,执行完成后再回滚;

  • VERBOSE:显示有关计划的其他信息。具体而言,包括计划树中每个节点的输出列列表、模式限定表和函数名称,始终使用其范围表别名标记表达式中的变量,并始终打印显示统计信息的每个触发器的名称。此参数默认为FALSE。

  • COSTS:包括每个计划节点的启动成本和总成本信息,以及估计的行数和每行的估计宽度。此参数默认为TRUE。

  • SETTINGS:包括有关配置参数的信息。具体来说,包括影响查询计划的选项,其值与内置默认值不同。此参数默认为FALSE。

  • BUFFERS:包括缓冲区使用的信息。特别是:共享块命中、读取、标记为脏和写入的次数、本地块命中、读取、标记为脏和写入的次数、以及临时块读取和写入的次数。只有当ANALYZE也被启用时,这个参数才能使用。它的默认被设置为FALSE。

  • WAL:包括WAL记录生成信息。具体来说,包括记录的数量等。此参数只能在同时启用ANALYZE时使用。默认为FALSE。

  • TIMING:在输出中包括实际启动时间和在每个节点上花费的时间。此参数只能在同时启用ANALYZE时使用。它默认为TRUE。

  • SUMMARY:在查询计划之后包括摘要信息(例如,总计时间信息)。使用ANALYZE时,默认情况下会包含摘要信息,但在其他情况下,默认情况不会包含摘要信息。但可以使用此选项启用摘要信息。EXPLAIN EXECUTE中的计划时间包括从缓存中获取计划所需的时间以及重新计划所需(如有必要)的时间。

  • FORMAT:指定输出格式,可以是TEXT、XML、JSON或YAML。非文本输出包含与文本输出格式相同的信息,但程序更容易解析。此参数默认为TEXT。

2.Explain相关参数

执行计划的代价计算采用的是假定的单位,与以下数据库参数有关(cost 值描述一个SQL执行的代价),可以根据主机的实际情况,调整参数值:

系统参数名

说明

默认值

seq_page_cost

顺序扫描page的成本

默认1.0,为基准

random_page_cost

随机扫描page的成本

默认4.0,以1.0为基准,4.0表示慢四倍

cpu_tuple_cost

处理一个数据行(元组)的CPU成本

默认0.01,以1.0为基准,0.01表示快100倍

cpu_index_tuple_cost

处理一个索引行(元组)的CPU成本

默认0.005,以1.0为基准,0.005表示快200倍

cpu_operator_cost

执行一次操作符或函数的CPU成本

默认0.0025,以1.0为基准,0.0025表示快400倍

parallel_tuple_cost

并行执行,从一个worker传输一个元组到另一个worker的成本

默认0.1

 

parallel_setup_cost

构建并行执行环境的成本

默认1000.0

上面的这些数据库参数越大表示越慢,查询优化就会选择其他更快的执行计划,比如走索引扫描路径。

3.执行计划解读

下面以一个具体的SQL例子来解读下执行计划:

图片

图7:Explain执行计划

cost=0.29..8.30  第一个0.29 表示估计的启动成本,即返回第一行需要多少cost值,后面一个8.30 表示估计所有的行都被搜索到时的总成本,即返回所有数据的成本。

rows=1 估计执行完成时输出的行数,即返回多少行。

width=8 估计在该计划结点输出的平均行宽度(以bytes为单位)。

actual time=0.017..0.019 第一个0.017表示返回第一行实际花费的时间,后面一个0.019表示返回所有数据的实际花费的时间。

rows=1 估计执行完成时输出的行数,即返回多少行。

loops=1 表示循环的次数。

Planning Time: 0.439 ms 表示生成执行计划的时间。

Execution Time: 0.036 ms 表示执行执行计划的时间。

Index Scan using test_optimize_const_idx on public.test_optimize_const 表示使用了索引扫描方式,使用的是表public.test_optimize_const的索引,索引名字是test_optimize_const_idx。Output: id, rel_id表示查询输出的字段,Index Cond: (test_optimize_const.id = 8) 表示索引的条件。

  

总结

AntDB-T查询优化至为关键,其为提升数据库查询效能之关键所在。通过正确的查询优化,数据库能够更为迅速地查找到所需要的数据并返回结果,进而提高响应速度以及吞吐量。同时也能减少服务器资源消耗,降低运营成本。此外,良好的查询性能也可以提高用户体验,增加系统可用性和稳定性。

本文主要讲述了AntDB-T查询优化的概念、引入查询优化带来的性能提升、查询优化的原理以及如何查看查询优化后的执行计划。限于篇幅,查询优化的子查询提升、外连接消除、谓词下推等相关内容未能一一举例说明,感兴趣的小伙伴请持续关注AntDB数据库公众号。

关于亚信安慧AntDB数据库

AntDB数据库始于2008年,在运营商的核心系统上,为全国24个省份的10亿多用户提供在线服务,具备高性能、弹性扩展、高可靠等产品特性,峰值每秒可处理百万笔电信核心交易,保障系统持续稳定运行近十年,并在通信、金融、交通、能源、物联网等行业成功商用落地。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1321273.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python【matplotlib】鼠标拖动滚动缩放坐标范围和拖动图例共存

背景 根据前面的博文: python【matplotlib】画图鼠标缩放拖动动态改变坐标轴范围 和Python【Matplotlib】图例可拖动改变位置 两个博文,博主考虑了一下,如何将两者的功能结合起来,让二者共存。 只需根据Python【Matplotlib】鼠标…

【音视频 | AAC】AAC音频编码详解

😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀 🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C、数据结构、音视频🍭 🤣本文内容🤣&a…

【GD32307E-START】06 ST7735 SPI-LCD显示模块移植

软硬件平台 GD32F307E-START Board开发板GCC Makefile1.8寸TFTLCD 分辨率128*160 驱动IC ST7735S 接口定义 序号引脚标号说明1GND接地2VCC5V/3.3V电源输入3SCKSPI总线时钟信号4SDASPI总线写数据信号5RESET液晶屏复位信号,低电平复位6DC液晶屏寄存器/数据选择信…

LinuxCNC系统安装

首先我们需要准备一个U盘来安装系统,然后进入Debian官网。操作系统处,点击“下载Debian”。 如果需要下载其他比较全版本,可以点击“其他下载链接”,选择DVD的安装,因为是国外的网站,最好不要选择网络安装。…

【每日OJ—有效的括号(栈)】

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 1、有效的括号题目: 1.1方法讲解: 1.2代码实现: 总结 前言 世上有两种耀眼的光芒,一种是正在升起的太阳&#…

机器学习:增强式学习Reinforcement learning

收集有标签数据比较困难的时候同时也不知道什么答案是比较好的时候可以考虑使用强化学习通过互动,机器可以自己知道什么结果是好的,什么结果是坏的 Outline 什么是RL Action就是一个functionEnvironment就是告诉这个Action是好的还是坏的 例子 Space i…

2023年度IT168技术卓越奖名单:亚信安慧AntDB数据库

信创卓越贡献奖:湖南亚信安慧科技有限公司 一句话点评:亚信安慧的核心交易数据库AntDB具有应用时间久(15年)、运行节点多(2000)、数据规模大(PB级)、产品稳定可靠(500项目…

L1-050:倒数第N个字符串

题目描述 给定一个完全由小写英文字母组成的字符串等差递增序列,该序列中的每个字符串的长度固定为 L,从 L 个 a 开始,以 1 为步长递增。例如当 L 为 3 时,序列为 { aaa, aab, aac, ..., aaz, aba, abb, ..., abz, ..., zzz }。这…

Spring Cloud + Vue前后端分离-第6章 通用代码生成器开发

Spring Cloud Vue前后端分离-第6章 通用代码生成器开发 6-1 代码生成器原理介绍 1.增加generator模块,用于代码生成 2.集成freemarker 通用代码生成器开发 FreeMarker 是一款模版引擎,通过模板生成文件,包括html页面,excel …

【经典LeetCode算法题目专栏分类】【第5期】贪心算法:分发饼干、跳跃游戏、模拟行走机器人

《博主简介》 小伙伴们好,我是阿旭。专注于人工智能AI、python、计算机视觉相关分享研究。 ✌更多学习资源,可关注公-仲-hao:【阿旭算法与机器学习】,共同学习交流~ 👍感谢小伙伴们点赞、关注! 分发饼干 class Solutio…

万兆网络之线路测速

网络测速有很多种方式,建议使用开源的iperf搭建测试 官方:iperf3(技术网站一般不被和谐,有部分可能被污染) Windows下载后解压即可运行 小技巧:如果你用的笔记本只有一个C盘,最好将免安装的软…

Zotero插件安装、问题、bug大全(随时更新)

Zotero插件安装、问题、bug大全(随时更新) 1. 插件安装2. 茉莉花(Jasminum)插件使用tips及可能遇到的问题2.1 更新2.2 未找到PDFtk Server的可执行文件 问题解决方法 3. Zotero Sci-hub插件相关问题3.1 Zotero Sci-hub插件有时抓取…

iOS问题记录 - iOS 17通过NSUserDefaults设置UserAgent无效

文章目录 前言开发环境问题描述问题分析解决方案最后 前言 最近维护一个老项目时遇到的问题。说起这老项目我就有点头疼,一个快十年前的项目,这么说你可能不觉得有什么,但是你想想Swift也才发布不到十年(2014年6月发布&#xff0…

DS排序--快速排序

Description 给出一个数据序列,使用快速排序算法进行从小到大的排序 排序方式:以区间第一个数字为枢轴记录 输出方式:每一步区间排序,都输出整个数组 –程序要求– 若使用C只能include一个头文件iostream;若使用C…

深度学习笔记_7经典网络模型LSTM解决FashionMNIST分类问题

1、 调用模型库,定义参数,做数据预处理 import numpy as np import torch from torchvision.datasets import FashionMNIST import torchvision.transforms as transforms from torch.utils.data import DataLoader import torch.nn.functional as F im…

2000年AMC8数学竞赛中英文真题典型考题、考点分析和答案解析

今天是2023年12月19日,距离2024年的AMC8正式考试倒计时一个月。 从战争中学习战争最有效。前几天,六分成长分析了2023年、2022年、2020、2019、2018、2017的AMC8真题的典型考题、考点和详细答案解析。 今天我们不再从2016年分析,来看看更早…

pytorch文本分类(三)模型框架(DNNtextCNN)

pytorch文本分类(三)模型框架(DNN&textCNN) 原任务链接 目录 pytorch文本分类(三)模型框架(DNN&textCNN)1. 背景知识深度学习 2. DNN2.1 从感知器到神经网络2.2 DNN的基本…

避坑指南:uni-forms表单在uni-app中的实践经验

​🌈个人主页:前端青山 🔥系列专栏:uni-app篇 🔖人终将被年少不可得之物困其一生 依旧青山,本期给大家带来JavaScript篇专栏内容:uni-app中forms表单的避坑指南篇 该篇章已被前端圈子收录,点此处进入即可查看更多优质内…

Pytorch nn.Linear()的基本用法与原理详解及全连接层简介

主要引用参考: https://blog.csdn.net/zhaohongfei_358/article/details/122797190 https://blog.csdn.net/weixin_43135178/article/details/118735850 nn.Linear的基本定义 nn.Linear定义一个神经网络的线性层,方法签名如下: torch.nn.Li…

AT32F403如何扩大SRAM

配置方法 使用雅特力的ICP 进行配置(可在官网下载) (1)当连接上芯片后,点击设备操作->选择字节 (2)选择224KB SRAM (3)然后点击应用到设备,(可以点击从设备加载,来看当前的配置) (4)打开keil5魔术棒图标 ,将Target中的IRAM1第二个选项从0x10000改为0x3800。…