达梦数据库在不修改SQL的情况下为SQL指定HINT

news2025/1/13 2:38:49

前言

   在Oracle中可以使用outline、SQL PROFILE等手段去在无需修改SQL语句的情况下,来保证SQL执行计划在不同硬件环境下相同,从而保证SQL语句在不同环境的执行效率。那么,在达梦数据库中则可以使用SF_INJECT_HINT系统函数达到类似的效果。

SF_INJECT_HINT使用介绍

SF_INJECT_HINT系统函数的功能是对指定SQL增加HINT。可通过SYSINJECTHINT视图查看已指定的SQL语句和对应的HINT;
使用方法如下:

SF_INJECT_HINT(SQL_TEXT,HINT_TEXT,NAME,DESCRIPTION,VALIDATA,FUZZY);

参数说明如下:

   SQL_TEXT:要指定HINT的SQL语句;
   HINT_TEXT:要为SQL指定的HINT;多个hint使用空格隔开;
   NAME:可以指定名称,或者设为NULL让系统自动创建名称;
   DESCRIPTION:对规则的详细描述,可为NULL;
   VALIDATA:规则是否生效,可为NULL,则为默认值TRUE;
   FUZZY:SQL的匹配规则为精准匹配或模糊匹配。值为TRUE或NULL时,模糊匹配;值为FALSE或缺省时,精准匹配; 

需要注意:

FUZZY参数在老的版本中是不支持的(DM V8 1-1-190附近的版本才开始支持)

使用时的限制条件如下:

(1)INI参数ENABLE_INJECT_HINT需设置为1;
(2)SQL只能是语法正确的增删改查语句;
(3)SQL会经过系统格式化,格式化之后的SQL和指定的规则名称必须全局唯一;
(4)HINT一指定,则全局生效;
(5)系统检查SQL匹配时,必须是整条语句完全匹配,不能是语句中子查询匹配;

使用场景:

通过SF_INJECT_HINT函数为SQL指定HINT的方式,适合在SQL执行计划较差或者走错(比如走了索引但回表代价高于全表扫描、表连接错误等情况)且调整SQL语句代价比较大的情况下使用。

SF_INJECT_HINT使用示例

(1)设置INI参数ENABLE_INJECT_HINT为1

ENABLE_INJECT_HINT参数表示是否启用SQL指定HINT的功能,0:不启用;1:启用,默认0。动态,会话级参数,修改后无需重启数据库生效。

SP_SET_PARA_VALUE(1,'ENABLE_INJECT_HINT',1);   

(2)会话级开启MONITOR_SQL_EXEC,方便使用ET查看SQL执行计划各个操作消耗的时间

sf_set_session_para_value('MONITOR_SQL_EXEC',1);

(3)首先查看测试SQL执行时间以及SQL执行计划各个操作的耗时

SQL语句如下:

select count(OBJECT_ID) from TAB1 WHERE OWNER='CTISYS';

SQL执行计划如下:

1   #NSET2: [3, 1, 78] 
2     #PRJT2: [3, 1, 78]; exp_num(1), is_atom(FALSE) 
3       #AAGR2: [3, 1, 78]; grp_num(0), sfun_num(1) slave_empty(0)
4         #BLKUP2: [3, 3477, 78]; IDX_TAB1_OWNER(TAB1)
5           #SSEK2: [3, 3477, 78]; scan_type(ASC), IDX_TAB1_OWNER(TAB1), scan_range['CTISYS','CTISYS']

使用et(sql执行号)查看执行计划中各个步骤的耗时情况:

SQL> ET(6007);

行号     OP     TIME(US)             PERCENT RANK                 SEQ         N_ENTER    
---------- ------ -------------------- ------- -------------------- ----------- -----------
1          PRJT2  4                    0%      6                    2           4
2          DLCK   7                    0%      5                    0           2
3          NSET2  218                  0.09%   4                    1           3
4          AAGR2  648                  0.26%   3                    3           467
5          SSEK2  29371                11.99%  2                    5           465
6          BLKUP2 214733               87.65%  1                    4           930

BLKUP2操作符表示通过rowid回表,即通过索引记录的ROWID访问表中的数据。索引返回多少行数据,回表就要回多少次,回表的次数太多会严重影响SQL性能。对于SQL中严重影响性能的回表操作,应尽可能的消除,在无法创建较好的组合索引的情况下,反而还不如走全表扫描高效。

(5)SQL语句中添加HINT

HINT的使用以及查看可以参考《DM8 DBA手册》或者达梦社区(https://eco.dameng.com)中相关文档。

使用hint让表不走IDX_TAB1_OWNER索引如下:

select /*+ no_index(TAB1 IDX_TAB1_OWNER)*/ count(OBJECT_ID) from TAB1 WHERE OWNER='CTISYS';

执行计划如下:

SQL> explain select /*+ no_index(TAB1 IDX_TAB1_OWNER)*/ count(OBJECT_ID) from TAB1 WHERE OWNER='CTISYS';

1   #NSET2: [18, 1, 78] 
2     #PRJT2: [18, 1, 78]; exp_num(1), is_atom(FALSE) 
3       #AAGR2: [18, 1, 78]; grp_num(0), sfun_num(1) slave_empty(0)
4         #SLCT2: [18, 3477, 78]; TAB1.OWNER = 'CTISYS'
5           #CSCN2: [18, 139099, 78]; INDEX33556683(TAB1)

ET查看执行计划各个操作耗时如下:

SQL> et(6105);

行号     OP    TIME(US)             PERCENT RANK                 SEQ         N_ENTER    
---------- ----- -------------------- ------- -------------------- ----------- -----------
1          PRJT2 4                    0.01%   6                    2           4
2          DLCK  9                    0.03%   5                    0           2
3          NSET2 99                   0.32%   4                    1           3
4          AAGR2 107                  0.34%   3                    3           467
5          SLCT2 2598                 8.29%   2                    4           930
6          CSCN2 28509                91.01%  1                    5           465

从上面测试SQL中执行计划每个步骤的耗时,可以发现全表扫描(CSCN2)耗时28ms,而上面走索引之后回表(BLKUP2)耗时214ms,在这种情况下走全表扫描效率会更快。

在SQL语句中添加hint需要修改程序代码中的SQL,而某些情况下需要在不修改SQL语句的情况下为SQL指定相应hint,这种情况下就可以使用SF_INJECT_HINT为SQL语句指定HINT。

(6)使用SF_INJECT_HINT为SQL语句指定HINT

SF_INJECT_HINT('select count(OBJECT_ID) from TAB1 WHERE OWNER=''CTISYS'';','no_index(TAB1 IDX_TAB1_OWNER)','INJECT_HINT_1',null,TRUE,FALSE);

上述语句表示的意思为:为SQL语句指定hint为no_index(TAB1 IDX_TAB1_OWNER),规则名称为INJECT_HINT_1,规则描述为空,并生效,SQL的匹配规则为精准匹配。

注意:

如果SQL语句中存在单引号,则在使用SF_INJECT_HINT时需要加单引号进行转义。

通过SYSINJECTHINT系统表可以查看相关信息:

SQL> select * from SYSINJECTHINT;

行号     NAME          DESCRIPTION VALIDATE
---------- ------------- ----------- --------
           SQL_TEXT                                               
           -------------------------------------------------------
           HINT_TEXT                     CREATOR CRTDATE                    INFO1      
           ----------------------------- ------- -------------------------- -----------
           INFO2      INFO3     
           ---------- ----------
1          INJECT_HINT_1 NULL        TRUE
           select count(OBJECT_ID) from TAB1 WHERE OWNER='CTISYS';
           no_index(TAB1 IDX_TAB1_OWNER) SYSDBA  2021-12-18 21:40:51.056164 0
           NULL       NULL

删除指定的INJECTHINT规则:

SF_DEINJECT_HINT('INJECT_HINT_1');

(7)使用SQL模糊匹配,仅使用部分SQL语句让符合规则的SQL语句使用指定HINT

遇到某些业务SQL语句比较长,而且语句中间空格等较多的情况下,这时如果SQL语句少了一个空格等,使用SQL语句精确匹配的规则可能存在指定HINT无法生效的情况。

示例:

以hint STAT为例,stat hint的作用如下:

image-20211218215736512

使用SF_INJECT_HINT为SQL语句执行stat(A 1000M)的hint,SF_INJECT_HINT中的SQL语句为’select OBJECT_ID’,SQL语句匹配规则为模糊匹配,如下:

SF_INJECT_HINT('select OBJECT_ID','STAT(A 1000M)','INJECT_HINT_2',null,TRUE,TRUE);

image-20211218220154076

查看效果:

image-20211218220438878

创建表TAB2,表结构与TAB1相同,数据为1条,执行SQL语句为:select OBJECT_ID,OBJECT_TYPE FROM TAB2 A; ,测试如下:

image-20211218220729984

可以看到,SQL语句模糊匹配时,执行的SQL语句必须与SF_INJECT_HINT规则中的SQL语句完全相同(包括SQL语句中的空格)。同时,指定的HINT对所有符合的SQL语句均生效。

简单总结

(1)在DM V8 1-1-190左右版本开始,SF_INJECT_HINT支持SQL模糊匹配,这对生产应用环境有非常大的帮助。由于很多业务SQL语句很长而且语句中的空格等也比较多,应用代码不好调整的情况下,使用模糊匹配可以非常方便的为SQL语句指定HINT让其走比较好的执行计划。

(2)SQL语句模糊匹配时,执行的SQL语句必须与SF_INJECT_HINT规则中的SQL语句完全相同(包括SQL语句中的空格)。同时,指定的HINT对所有符合的SQL语句均生效。

更多资讯请上达梦技术社区了解:https://eco.dameng.com

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

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

相关文章

Java学习笔记 --- 异常

一、基本介绍 Java语言中,将程序执行中发生的不正常情况称为“异常”。(开发过程中的语法错误和逻辑错误不是异常) 执行过程中所发生的异常事件可以分为两类 1、Error(错误):Java虚拟机无法解决的严重问…

十月了,请问2022届的同学们都找到工作了吗?

今年的就业大环境就不多说了,大家都知道。一边是超千万规模的应届毕业生,叠加教培、地产等行业裁员;另一边则是疫情反复影响之下,企业瘦身裁员、停招、缩招。在白领性质的劳动力市场,劳动力供给严重大于需求&#xff0…

【C语言】解题训练

目录 字符串左旋 方法1 方法2 字符串旋转结果判断 方法1 方法2 杨氏矩阵 位段 题目1 题目2 联合体 题目1 题目2 有序序列合并 变种水仙花 找单身狗 字符串左旋 实现一个函数,可以左旋字符串中的k个字符。 例如: ABCD左旋一个字符得到…

纷享销客联合B.P商业伙伴携手30+企业CEO走进南天信息

数字化智能化建设的当下,数字化服务商承担着承上启下的核心力量。企业数字化转型成为刚需,意味着ICT企业的市场前景持续乐观,但在疫情和竞争加剧之下,企业发展也遭遇增长的挑战,如何在数字中国的趋势之下,乘…

大学网课搜题公众号系统

大学网课搜题公众号系统 本平台优点: 多题库查题、独立后台、响应速度快、全网平台可查、功能最全! 1.想要给自己的公众号获得查题接口,只需要两步! 2.题库: 题库:题库后台(点击跳转&#xf…

【从小白到大白05】c和c++内存管理

c和c内存管理 文章目录c和c内存管理c内存管理方式new/delete操作内置类型new申请动态空间delete释放空间new和delete操作自定义类型operator new与operator delete函数new[]和delete[]定位new(placement-new)总结以上内存泄露以上就是全部内容啦&#xf…

WPS-JS宏开发-基础知识-03-三大基本结构

系统:Windows 11 软件:WPS表格11 本系列介绍一款类Excel的软件,WPS表格当然也是介绍其宏开发,不同的是,使用的JS宏会同样介绍多个系列,本系列介绍一些基础知识 Part 1: 三大逻辑结构 一个具体的…

如何给字符串字段加索引?

1.引例 现在的系统中,很多都会包含邮箱字段,那要如何给这个字段建立索引呢? 假设,现在维护了一个用户表,其中包含邮箱,定义如下: mysql>create table SUser(ID int primary key,email var…

OpenGL之多边形偏移、雾效、纹理映射

1.1 OpenGL中可以设置物体的点、线、面绘制模式。如果需要同时绘制多种模式,如下以面和线模式绘制两遍模型,可以看到线不连续,当镜头推远推近时会出现闪烁现象。 void glPolygonMode(GLenum face,GLenum mode);face :GL_FRONT,GL…

分治暴力求解最近点对问题 + 时间性能量化分析

Catalogue1 Intro2 Problem3 Time performance analysis4 Solution5 Reference1 Intro 本文旨在讨论分治和暴力在求解最近点对问题时的时间性能问题,关于解题部分不做过多讲解,只附上相关代码。 2 Problem 给定平面上N个点,找出其中的一对…

【Linux】第七章 进程控制(进程创建+进程终止+进程等待+进程替换+min_shell)

🏆个人主页:企鹅不叫的博客 ​ 🌈专栏 C语言初阶和进阶C项目Leetcode刷题初阶数据结构与算法C初阶和进阶《深入理解计算机操作系统》《高质量C/C编程》Linux ⭐️ 博主码云gitee链接:代码仓库地址 ⚡若有帮助可以【关注点赞收藏】…

【路径规划-多式联运】基于遗传算法求解多式联运运输问题(考虑碳交易)附Matlab代码

✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,matlab项目合作可私信。 🍎个人主页:Matlab科研工作室 🍊个人信条:格物致知。 更多Matlab仿真内容点击👇 智能优化算法 …

字符串和编码那些事

一、字符编码 1. ASCII字符编码 因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理。最早的计算机在设计时采用8个比特(bit)作为一个字节(byte) 由于计算机是美国人发明的&#…

【Apache Spark 】第 11 章使用 Apache Spark 管理、部署和扩展机器学习管道

🔎大家好,我是Sonhhxg_柒,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流🔎 📝个人主页-Sonhhxg_柒的博客_CSDN博客 📃 🎁欢迎各位→点赞…

编程神器Copilot逐字抄袭他人代码?

自面世后就饱受争议的 GitHub Copilot 编程神器最近又遭遇舆论风暴。 日前,德州农工大学的一位计算机科学教授 Tim Davis 在推特上发文称, GitHub Copilot 在没有标注来源也没有 LGPL 许可的情况下,输出了大量应该受版权保护的代码。 Tim Davis 还发了自己和 GitHub Copil…

90后汕头返种水稻 国稻种芯·中国水稻会:广东新农人田保姆

90后汕头返种水稻 国稻种芯中国水稻会:广东新农人田保姆 南方日报 张伟炜 新闻中国采编网 中国新闻采编网 谋定研究中国智库网 中国农民丰收节国际贸易促进会 国稻种芯中国水稻节 中国三农智库网-功能性农业农业大健康大会报道:“5月稻谷病虫害防护非常…

机器学习(周志华)课后习题

第1章 绪论 1.1 表1.1若只包含编号1和4的两个样例,试给出相应的版本空间。 版本空间:与训练及一致的假设集合。 色泽青绿,根蒂*,敲声*; 色泽*,根蒂蜷缩,敲声*; 色泽*,根…

nuxt.js 进行项目重构-首页

nuxt.js 也是基于vue 的 那么就离不开组件化开发 我们按照组件结构来进行分析 navTop 页面的头部 通用组件 分隔了三个位置 适用于大多数头部 且预留插槽 <template><div class"nav-top"><div class"left"><slot name"left…

Spring5入门到实战------10、操作术语解释--Aspectj注解开发实例。AOP切面编程的实际应用

1、操作术语 1.1、连接点 类里面哪些方法可以被增强、这些方法被称为连接点。比如&#xff1a;用户控制层有登录、注册、修改密码、修改信息等方法。假如只有登录类和注册类可以被增强&#xff0c;登录和注册方法就称为连接点 1.2、切入点 实际被真正增强的方法&#xff0c…

C++ 【UVA488】Triangle Wave

&#x1f4cb; 个人简介 &#x1f496;大家好&#xff0c;我是2022年3月份新人榜排名第三的 ༺Blog༒Hacker༻ &#x1f389;支持我&#xff1a;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; &#x1f4ac;格言&#xff1a;༺永做优质༒programmer༻ &#x1f4e3; 系列专栏&am…