循序渐进丨MogDB 数据库新特性之SQL PATCH绑定执行计划
1
SQL PATCH
熟悉 Oracle 的DBA都知道,生产系统出现性能问题时,往往是SQL走错了执行计划,紧急情况下,无法及时修改应用代码,DBA可以采用多种方式针对于某类SQL进行执行计划绑定,比如SQL Profile、SPM、SQL Plan Base等等。
MogDB 数据库5.0版本引入了SQL PATCH的特性,SQL PATCH能够在避免直接修改用户业务语句的前提下对查询执行的方式做一定调整。在发现查询语句的执行计划、执行方式未达预期的场景下,可以通过创建查询补丁的方式,使用Hint对查询计划进行调优或对特定的语句进行报错短路处理。
SQL PATCH主要设计给DBA、运维人员及其他需要对SQL进行调优的角色使用,用户通过其他运维视图或定位手段识别到业务语句存在计划不优导致的性能问题时,可以通过创建SQL PATCH对业务语句进行基于Hint的调优。目前支持行数、扫描方式、连接方式、连接顺序、PBE custom/generic计划选择、语句级参数设置、参数化路径的Hint。
特性约束
-
仅支持针对Unique SQL ID打PATCH,如果存在Unique SQL ID冲突,用于Hint调优的SQL PATCH可能影响性能,但不影响语义正确性。
仅支持不改变SQL语义的Hint作为PATCH,不支持SQL改写。
不支持逻辑备份、恢复。
不支持创建时校验PATCH合法性,如果PATCH的Hint存在语法或语义错误,不影响查询正确执行。
仅初始用户、运维管理员、监控管理员、系统管理员用户有权限执行;库之间不共享,创建SQL PATCH时需要连接目标库。
配置集中式备机可读时,需要指定主机执行SQL PATCH创建/修改/删除函数调用,备机执行报错。
SQL PATCH同步给备机存在一定延迟,待备机回放相关日志后PATCH生效。
不支持对存储过程中的SQL语句生效,当前机制不会对存储过程内语句生成Unique SQL ID。
用于规避的Abort Patch不建议在数据库中长期使用,只应该作为临时规避方法;遇到内核问题所导致的特定语句触发数据库服务不可用问题,需要尽快修改业务或升级内核版本解决问题;并且升级后由于Unique SQL ID生成方法可能变化,可能导致规避方法失效。
当前,除DML语句之外,其他SQL语句(如CREATE TABLE等)的Unique SQL ID是对语句文本直接哈希生成的,所以对于此类语句,SQL PATCH对大小写、空格、换行等敏感,即不同的文本的语句,即使语义相对,仍然需要对应不同的SQL PATCH;对于DML,则同一个SQL PATCH可以对不同入参的语句生效,并且忽略大小写和空格。
依赖关系
需要开启enable_resource_track参数并且设置instr_unique_sql_count大于0。对于不同的语句,如果生成的Unique SQL ID冲突,会导致SQL PATCH错误地命中预期外的其他语句。其中用于调优的Hint PATCH副作用相对较小,Abort Patch需要谨慎使用。
2
实际案例
1、创建表
创建表t1和t2;
create table t1(name char(10),id int);
create table t2(name char(10),id int);
2、构造数据
INSERT INTO t1 (name, id)
SELECT 'data_'|| generate_series(1, 1000), generate_series(1, 1000);INSERT INTO t2 (name, id)
SELECT 'data_'|| generate_series(1, 1000), generate_series(1, 1000);CREATE INDEX idx_t1 ON t1 (id);
CREATE INDEX idx_t2 ON t2 (id);
3、获取unique_query_id
执行SQL并获取unique_query_id、执行计划:
set track_stmt_stat_level = 'L1,L1'; --track_stmt_stat_level解释:
该参数分为两部分:
--形式为'full sql stat level, slow sql stat level'。
--级别(L2 > L1 > L0),L1在L0的基础上记录了执行计划,L2在L1的基础上记录了锁的详细信息select * from t1 a, t2 b where a.id = b.id;name | id | name | id
------------+------+------------+------data_1 | 1 | data_1 | 1data_2 | 2 | data_2 | 2data_3 | 3 | data_3 | 3data_4 | 4 | data_4 | 4data_5 | 5 | data_5 | 5data_6 | 6 | data_6 | 6data_7 | 7 | data_7 | 7。。。。
(1000 row)
4、获取查看执行计划
走的全表扫描hash jion执行计划:
explain select * from t1 a, t2 b where a.id = b.id;QUERY PLAN
--------------------------------------------------------------------------Aggregate (cost=60.75..60.76 rows=1 width=8)-> Hash Join (cost=28.50..58.25 rows=1000 width=0)Hash Cond: (a.id = b.id)-> Seq Scan on t1 a (cost=0.00..16.00 rows=1000 width=4)-> Hash (cost=16.00..16.00 rows=1000 width=4)-> Seq Scan on t2 b (cost=0.00..16.00 rows=1000 width=4)
5、查询unique_query_id
select unique_query_id,query,start_time from dbe_perf.statement_history where query like '%from t1 a%';unique_query_id | query | start_time
-----------------+----------------------------------------------------+-------------------------------3366573496 | select * from t1 a, t2 b where a.id = b.id; | 2024-01-19 10:08:56.994391+08也可以通过statement_history查询执行计划
select start_time,query_plan from dbe_perf.statement_history where unique_query_id = 3366573496;start_time | query_plan
-------------------------------+--------------------------------------------------------------------------2024-01-19 10:08:56.994391+08 | Datanode Name: dn_6001_6002 +| Hash Join (cost=28.50..58.25 rows=1000 width=30) +| Hash Cond: (a.id = b.id) +| -> Seq Scan on t1 a (cost=0.00..16.00 rows=1000 width=15) +| -> Hash (cost=16.00..16.00 rows=1000 width=15) +| -> Seq Scan on t2 b (cost=0.00..16.00 rows=1000 width=15)+| +
6、SQL PATCH绑定执行计划
call dbe_sql_util.create_hint_sql_patch('enmo patch',3366573496,'indexscan(a)');create_hint_sql_patch
-----------------------t
(1 row)--参数说明:
enmo patch --SQL PATCH name
3366573496 --unique_query_id
indexscan(a) --Hint文本
7、验证SQL PATCH
执行并检查新的执行计划是否生效:
select * from t1 a, t2 b where a.id = b.id;name | id | name | id
------------+------+------------+------data_1 | 1 | data_1 | 1data_2 | 2 | data_2 | 2data_3 | 3 | data_3 | 3data_4 | 4 | data_4 | 4data_5 | 5 | data_5 | 5data_6 | 6 | data_6 | 6data_7 | 7 | data_7 | 7。。。。explain select * from t1 a, t2 b where a.id = b.id;
NOTICE: Plan influenced by SQL hint patchQUERY PLAN
------------------------------------------------------------------------------Hash Join (cost=28.50..86.50 rows=1000 width=30)Hash Cond: (a.id = b.id)-> Index Scan using idx_t1 on t1 a (cost=0.00..44.25 rows=1000 width=15) --这里走了索引,表示SQL patch生效-> Hash (cost=16.00..16.00 rows=1000 width=15)-> Seq Scan on t2 b (cost=0.00..16.00 rows=1000 width=15)
(5 rows)
查看statement_history的执行计划:
select query_plan,to_char(start_time,'yyyymmdd-hh24:mi:ss') starttime
from dbe_perf.statement_history
where unique_query_id = 3366573496
order by start_time;Datanode Name: dn_6001_6002 +| 20240119-10:09:54Hash Join (cost=28.50..86.50 rows=1000 width=30) +| Hash Cond: (a.id = b.id) +| -> Index Scan using idx_t1 on t1 a (cost=0.00..44.25 rows=1000 width=15)+| -> Hash (cost=16.00..16.00 rows=1000 width=15) +| -> Seq Scan on t2 b (cost=0.00..16.00 rows=1000 width=15) +| +| |
查看数据库内已定义的SQL Patch:
select patch_name,unique_sql_id,enable,hint_string from gs_sql_patch;patch_name | unique_sql_id | enable | hint_string
------------+---------------+--------+--------------enmo patch | 3366573496 | t | indexscan(a)show_sql_patch查看SQL PATCH内容
MogDB=# select DBE_SQL_UTIL.show_sql_patch('enmo patch');show_sql_patch
-------------------------------------(3366573496,t,f,"indexscan(a)")
(1 row)
8、Abort Patch
使用Abort PATCH对特定语句进行提前报错规避:
MogDB=# select * from dbe_sql_util.drop_sql_patch('enmo patch'); -- 删去enmo patchdrop_sql_patch
----------------t
(1 row)
MogDB=# select * from dbe_sql_util.create_abort_sql_patch('patch2', 3366573496); -- 对该语句的Unique SQL ID创建Abort Patchcreate_abort_sql_patch
------------------------t
(1 row)MogDB=# select * from t1 a, t2 b where a.id = b.id; -- 再次执行语句会提前报错
ERROR: Statement 3366573496 canceled by abort patch patch2
9、关闭特定SQL Patch
disable enmo patch
call dbe_sql_util.disable_sql_patch('enmo patch');
执行SQL并检查执行计划是否恢复原始状态:
MogDB=# select query_plan,to_char(start_time,'yyyymmdd-hh24:mi:ss') starttime
MogDB-# from dbe_perf.statement_history
MogDB-# where unique_query_id = 3366573496
MogDB-# order by start_time;query_plan | starttime
--------------------------------------------------------------------------+-------------------Datanode Name: dn_6001_6002 +| 20240119-13:24:52Nested Loop (cost=0.00..340.00 rows=1000 width=30) +| -> Seq Scan on t1 a (cost=0.00..16.00 rows=1000 width=15) +| -> Index Scan using idx_t2 on t2 b (cost=0.00..0.31 rows=1 width=15)+| Index Cond: (id = a.id) +| +| | Datanode Name: dn_6001_6002 +| 20240119-13:31:49Hash Join (cost=28.50..58.25 rows=1000 width=30) +| Hash Cond: (a.id = b.id) +| -> Seq Scan on t1 a (cost=0.00..16.00 rows=1000 width=15) +| -> Hash (cost=16.00..16.00 rows=1000 width=15) +| -> Seq Scan on t2 b (cost=0.00..16.00 rows=1000 width=15) +| +|
最新的执行计划已经还原成hash jion。
MogDB 数据库官方文档参考:
-
SQL PATCH特性描述:https://docs.mogdb.io/zh/mogdb/v5.0/sql-patch#特性描述
track_stmt_stat_level:https://docs.mogdb.io/zh/mogdb/v5.0/query#track_stmt_stat_level
关于作者
许玉晨,云和恩墨 MogDB 技术支持工程师,有12年左右的金融、保险、政府、地税、运营商等业务关键型系统的运维经验,曾担任公司异常恢复东区接口人,负责紧急异常恢复工作,目前负责国产化MogDB数据库的推广工作。
数据驱动,成就未来,云和恩墨,不负所托!
云和恩墨创立于2011年,以“数据驱动,成就未来”为使命,是智能的数据技术提供商。我们致力于将数据技术带给每个行业、每个组织、每个人,构建数据驱动的智能未来。
云和恩墨在数据承载(分布式存储、数据持续保护)、管理(数据库基础软件、数据库云管平台、数据技术服务)、加工(应用开发质量管控、数据模型管控、数字化转型咨询)和应用(数据服务化管理平台、数据智能分析处理、隐私计算)等领域为各个组织提供可信赖的产品、服务和解决方案,围绕用户需求,持续为客户创造价值,激发数据潜能,为成就未来敏捷高效的数字世界而不懈努力。
相关文章:

循序渐进丨MogDB 数据库新特性之SQL PATCH绑定执行计划
1 SQL PATCH 熟悉 Oracle 的DBA都知道,生产系统出现性能问题时,往往是SQL走错了执行计划,紧急情况下,无法及时修改应用代码,DBA可以采用多种方式针对于某类SQL进行执行计划绑定,比如SQL Profile、SPM、SQL …...
【论文阅读随笔】RoPE/旋转编码:ROFORMER: ENHANCED TRANSFORMER WITH ROTARY POSITION EMBEDDING
文章目录 1.目的:通过绝对位置编码的方式实现相对位置编码2.理解RoPE,在我看来有几个需要注意的点:3.本文相关复数概念:3.1.复数乘法的几何意义3.2.复数内积 VS. 复数乘法 4.REF: 1.目的:通过绝对位置编码的…...
数据挖掘
一.数据仓库概述: 1.1数据仓库概述 1.1.1数据仓库定义 数据仓库是一个用于支持管理决策的、面向主题、集成、相对稳定且反映历史变化的数据集合。 1.1.2数据仓库四大特征 集成性(Integration): 数据仓库集成了来自多个不同来源…...

java SSM旅游景点与公交线路查询系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计
一、源码特点 java SSM旅游景点与公交线路查询系统是一套完善的web设计系统(系统采用SSM框架进行设计开发,springspringMVCmybatis),对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系…...
解决Git报错:fatal: detected dubious ownership in repository at
在通过 Git Bash 提交项目代码时输入 git add . 命令后,报错:fatal: detected dubious ownership in repository at 这是因为该项目的所有者与现在的用户不一致 比如说: 该项目的所有者是 Administrator,而当前用户是 YuYang, 那…...

网络协议常见问题
网络协议常见问题 OSI(Open Systems Interconnection)模型OSI 封装 TCP/IP协议栈IP数据报的报头TCP头格式UDP头格式TCP (3-way shake)三次握手建立连接:为什么三次握手才可以初始化 Socket、序列号和窗口大小并建立 TCP 连接。每次建立TCP连接…...

人工智能的迷惑行为
目录 前言1 人工智能的“幽默”瞬间1.1 语义误解1.2 逻辑错误 2 技术原理探究2.1 算法设计缺陷2.2 数据处理不当 3 社会影响分析3.1 信任度下降3.2 技术担忧 结语 前言 随着人工智能技术的迅猛发展,各类AI大模型如ChatGPT、文心一言、通义千问等纷纷登场࿰…...
XR技术:短剧制作的全新纪元
在数字技术的浪潮中,XR(扩展现实)技术以其独特的魅力,正在为短剧制作带来革命性的突破。这种融合了虚拟现实、增强现实和混合现实等先进技术的创新工具,正逐渐改变着短剧制作的传统模式,引领着短剧艺术走向…...

安卓 OpenGL ES 学习笔记
文章目录 OpenGL 学习笔记OpenGL 是什么?OpenGL ES是什么?怎么用?hello world如何实现动画效果 参考文章 OpenGL 学习笔记 OpenGL 是什么? OpenGL(Open Graphics Library)是一个跨平台的图形编程接口&…...

git分布式管理-头歌实验冲突处理、忽略文件
一、解决冲突 任务描述 在团队协作开发过程中,可能你和团队中的其他成员,都修改了某个文件的某一部分内容,且其他成员已将该修改推送到了远程仓库。这样当你需要合并他的代码的时候,可能就会在内容上出现冲突,这个时候…...

【实战项目】网络编程:在Linux环境下基于opencv和socket的人脸识别系统--C++实现
🌞前言 这里我们会实现一个项目:在linux操作系统下基于OpenCV和Socket的人脸识别系统。 目录 🌞前言 🌞一、项目介绍 🌞二、项目分工 🌞三、项目难题 🌞四、实现细节 🌼4.1 关…...

零售EDI:劳氏 Lowe‘s EDI项目案例
通过 EDI,企业与Lowes之间可以直接交换各种商业文档,如订单、发票、收据等,从而实现信息的实时交换,提高了供应链的效率和准确性。在现代供应链管理中,EDI 已经成为了不可或缺的重要工具。 作为一家拥有多条业务线的企…...

为什么不用 index 做 key?
“在 Vue 中,我们在使用 v-for 渲染列表的时候,为什么要绑定一个 key?能不能用 index 做 key?” 在聊这个问题之前我们还得需要知道 Vue 是如何操作 DOM 结构的。 虚拟DOM 我们知道,Vue 不可以直接操作 DOM 结构&am…...

Linux虚拟机安装Redis
官网下载压缩包:官网链接,然后将对应的tar.gz压缩包放入虚拟机下的/opt目录下。由于redis是C语言开发的,因此需要安装gcc编译器来编译代码,我们下载的压缩包里面是源代码,需要编译。通过yum install gcc指令下载C语言的…...

网络安全: Kali Linux 进行 SSH 渗透与防御
目录 一、实验 1.环境 2.nmap扫描目标主机 3.Kali Linux 进行 SSH 渗透 3.Kali Linux 进行 SSH 防御 二、问题 1.SSH有哪些安全配置 一、实验 1.环境 (1)主机 表1 主机 系统版本IP备注Kali Linux2022.4 192.168.204.154(动态&…...

近年来文本检测相关工作梳理
引言 场景文本检测任务,一直以来是OCR整个任务中最为重要的一环。虽然有一些相关工作是端对端OCR工作的,但是从工业界来看,相关落地应用较为困难。因此,两阶段的OCR方案一直是优先考虑的。 在两阶段中(文本检测文本识…...
文件系统事件监听
文件系统事件和网络IO事件一样,也可以通过epoll或者IOCP 事件管理器统一调度,当所监控的文件或文件夹发生了增删改的事件时,就会触发事件回调,进行事件处理。很常见的应用,如配置文件立即生效功能,就可以通…...
探秘HTTPS:如何通过SSL/TLS保证网络通信安全
目录 引言 详解HTTPS加密实现机制 SSL/TLS工作原理 结论 引言 随着网络安全威胁的日益增加,HTTPS通过SSL(Secure Sockets Layer)和TLS(Transport Layer Security)协议提供的加密技术变得至关重要。这些技术保证了用…...

Java算法之动态规划
Java算法之动态规划 前言 最近这一段时间一直在刷算法题,基本上一有时间就会做一两道,这两天做了几道动态规划的问题,动态规划之前一直是我比较头疼的一个问题,感觉好复杂,一遇到这样的问题就想跳过,昨…...
C++从零开始的打怪升级之路(day47)
这是关于一个普通双非本科大一学生的C的学习记录贴 在此前,我学了一点点C语言还有简单的数据结构,如果有小伙伴想和我一起学习的,可以私信我交流分享学习资料 那么开启正题 今天分享的是关于set和map的知识点 1.关联式容器 在前面&#…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...

linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...

Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...

CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...

有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...