news 2026/4/15 20:05:20

DM HINT 注入和持久化绑定计划

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
DM HINT 注入和持久化绑定计划

一、 区别

1、 hint注入

Hint注入是通过系统函数为SQL语句动态添加优化器指令的技术。通过SQL注释语法(/+ ... /)向优化器传递指令,干预其生成执行计划的决策过程(如强制索引、连接顺序)。通过系统函数 sf_inject_hint 创建全局规则,将HINT指令与特定SQL绑定,无需修改原SQL文本即可干预优化器行为。规则存储在系统视图 SYSINJECTHINT 中,由数据库自动匹配应用。通过参数ENABLE_INJECT_HINT=1全局开启Hint注入。 核心特点:

  1. )无需修改SQL文本。
  2. )DDL变更导致失效,表结构变更(如删除索引)后,强制索引的HINT会报错。
  3. )修改规则后,SQL仍使用旧执行计划,需手动清理计划缓存。
  4. )支持按SQL文本绑定和按HASH_VALUE绑定。

2、持久化绑定计划

持久化绑定计划指将已生成的执行计划持久化存储至系统表(SYSPLNINFO)中,确保数据库重启后仍可加载使用,从而避免执行计划因环境变化(如迁移、升级)而失效,保障性能稳定性。数据库重启后通过参数LOAD_BINDED_PLN=1自动加载,确保计划跨会话、跨重启的稳定性。 核心特点:

  1. )固化现有计划:跳过优化器阶段:直接复用存储的计划,避免因统计信息更新、索引变更等导致执行计划变动。
  2. )持久化存储:计划存入系统表,不受重启影响。
  3. )表结构变更(如删列、改类型)会导致绑定计划自动失效。
  4. )支持按SQL文本绑定和按HASH_VALUE绑定。
  5. )分为内存绑定与持久化绑定

绑定状态标识:在动态视图 V$CACHEPLN 中通过 BINDED 字段区分绑定类型:

'N':未绑定 'M':内存绑定(重启失效) 'P':持久化绑定 'B':内存绑定与持久化绑定同时生效。

二、适用场景

1、hint注入

  1. )紧急性能问题修复:当关键SQL因优化器缺陷(如错误选择索引或连接方式)导致性能骤降时,通过Hint注入强制指定执行路径。无需重启应用或修改SQL文本,实时生效。
  2. )规避全局参数风险:需调整优化器参数(如OPTIMIZER_OR_NBEXP),但全局修改会影响其他业务SQL。会话级或SQL级精准控制,避免全局参数副作用。
  3. )解决统计信息失真问题:统计信息未及时更新或采样率不足导致计划劣化(如全表扫描替代索引扫描)。

2、持久化绑定计划

  1. )核心交易系统性能保障:高频交易类SQL(如支付、清算)需绝对稳定的执行计划,避免因统计信息更新、索引变更等导致计划突变引发性能抖动。计划存入系统表 SYSPLNINFO,重启后通过 LOAD_BINDED_PLN=1 自动加载,彻底规避计划漂移风险。
  2. )统计信息采集不及时或采样率不足时,优化器可能生成劣质计划(如全表扫描替代索引扫描)。在统计信息准确时绑定最优计划,后续统计信息更新不会触发计划重生成。
  3. )数据库迁移/升级场景:跨版本升级或异构迁移(如Oracle→达梦)时,需保持原执行计划一致性,避免因优化器差异导致性能回退。

三、操作步骤

准备测试环境

创建测试表

create table DMHR.TAB01 ( ID INT not null , NAME VARCHAR2(10), ADDRESS VARCHAR2(10), primary key("ID") );

创建测试数据

insert into DMHR.TAB01 values(1,'Tony','Beijing'); insert into DMHR.TAB01 values(2,'Jason','USA'); insert into DMHR.TAB01 values(3,'Tracy','JP'); commit;

检查默认的执行计划

select * from DMHR.TAB01 t where t.ID=1; 1 #NSET2: [1, 1, 112] 2 #PRJT2: [1, 1, 112]; exp_num(4), is_atom(FALSE) 3 #BLKUP2: [1, 1, 112]; INDEX33555511(T) 4 #SSEK2: [1, 1, 112]; scan_type(ASC), INDEX33555511(TAB01 as T), scan_range[1,1], is_global(0)

强制不走索引

select /*+ NO_INDEX(t INDEX33555511) */ * from DMHR.TAB01 t where t.ID=1; 1 #NSET2: [1, 1, 112] 2 #PRJT2: [1, 1, 112]; exp_num(4), is_atom(FALSE) 3 #SLCT2: [1, 1, 112]; T.ID = 1 SLCT_PUSHDOWN(TRUE) 4 #CSCN2: [1, 3, 112]; INDEX33555510(TAB01 as T) NEED_SLCT(TRUE); btr_scan(1)

1、hint注入

1)根据sql模糊匹配

可通过SYSINJECTHINT 视图查看已指定的SQL 语句和对应的HINT。 select * from SYSINJECTHINT ; 如需修改注入的sql信息,可先删除INJECT,再重新创建,例: SF_DEINJECT_HINT 函数可以将设置INJECT hint删除。 sf_deinject_hint('TESTJOIN',false); 添加INJECT语法: sf_inject_hint( sql_text => ' select * from v$sessions a ,v$session_stat b where a.sess_id=b.sessid;', hint_text =>'use_nl(a,b)', name =>'TESTJOIN', description => 'this is a test join hint.', validate => true, fuzzy => true, --模糊匹配 need_clear=>false --不清空全库执行计划 ); 0 测试案例: 通过参数ENABLE_INJECT_HINT=1全局开启Hint注入 sp_set_para_value(1,'ENABLE_INJECT_HINT',1) sf_inject_hint( sql_text => 'select * from DMHR.TAB01 t where t.ID=1;', hint_text =>'NO_INDEX(t INDEX33555511) ', name =>'TESTJOIN', description => 'this is a test join hint.', validate => true, fuzzy => true, --模糊匹配 need_clear=>false --不清空全库执行计划 ); 检查新产生的注入: select * from SYSINJECTHINT; TESTJOIN this is a test join hint. TRUE <长文本> <长文本> SYSDBA 2025-12-26 12:45:38.373365 1 NULL NULL 检查SQL 产生的执行计划: select * from DMHR.TAB01 t where t.ID=1; <===一定要完全和绑定是的SQL。 1 #NSET2: [1, 1, 112] 2 #PRJT2: [1, 1, 112]; exp_num(4), is_atom(FALSE) 3 #SLCT2: [1, 1, 112]; T.ID = 1 SLCT_PUSHDOWN(TRUE) 4 #CSCN2: [1, 3, 112]; INDEX33555510(TAB01 as T) NEED_SLCT(TRUE); btr_scan(1) 检查是否命中了hint select * from V$INJECT_HINT_INFO; 1836374296 select * from DMHR.TAB01 t where t.ID=1; TESTJOIN NO_INDEX(t INDEX33555511) 2025-12-26 12:47:56 2025-12-26 12:47:56 1 Y TRUE

2)根据sql_text_id 绑定

--查询sql_text_id SELECT SQL_TEXT_ID,SQL_TEXT FROM SYS.V$SQLTEXT WHERE SQL_TEXT LIKE 'select * from DMHR.TAB01 t where t.ID=1;'; sn5u4cg7brg5h select * from DMHR.TAB01 t where t.ID=1; --清除之前的HINT 注入 SF_DEINJECT_HINT('TESTJOIN'); --确认之前的HINT 被清除 select * from SYSINJECTHINT; --使用sql_text_id进行hint注入 SF_INJECT_HINT('sn5u4cg7brg5h','NO_INDEX(t INDEX33555511)','TESTJOIN01','',TRUE,2); --sql_text:待注入 HINT 规则的 SQL 语句。fuzzy 参数类型为 INT 时,值为 2 表示支持通过 sql_text_id 指定待注入的 SQL 语句,sql_text_id 字段可通过 V$SQLTEXT 视图进行查询 --validate:HINT 规则是否生效。TRUE 是;FALSE 否 确认新HINT 的注入 select * from SYSINJECTHINT; 检查SQL 的执行计划 select * from DMHR.TAB01 t where t.ID=1; 1 #NSET2: [1, 1, 112] 2 #PRJT2: [1, 1, 112]; exp_num(4), is_atom(FALSE) 3 #SLCT2: [1, 1, 112]; T.ID = 1 SLCT_PUSHDOWN(TRUE) 4 #CSCN2: [1, 3, 112]; INDEX33555510(TAB01 as T) NEED_SLCT(TRUE); btr_scan(1) 检查HINT 的命中情况 select * from V$INJECT_HINT_INFO;

2、持久化绑定计划

1)清空执行计划缓存

sp_clear_plan_cache(); 删除上面的HINT 注入 SF_DEINJECT_HINT('TESTJOIN01');

2)执行SQL 生成新的待绑定的执行计划

注意:需要实际执行

select /*+ NO_INDEX(t INDEX33555511) */ * from DMHR.TAB01 t where t.ID=1; 1 #NSET2: [1, 1, 112] 2 #PRJT2: [1, 1, 112]; exp_num(4), is_atom(FALSE) 3 #SLCT2: [1, 1, 112]; T.ID = 1 SLCT_PUSHDOWN(TRUE) 4 #CSCN2: [1, 3, 112]; INDEX33555510(TAB01 as T) NEED_SLCT(TRUE); btr_scan(1)

3)持久化绑定

获取模式的 ID SELECT SCHID FROM SYSOBJECTS WHERE NAME='SYSDBA' AND TYPE$='SCH' 0 获取SQL 的HASH_VALUE SELECT HASH_VALUE FROM V$CACHEPLN WHERE SQLSTR LIKE 'select /*+ NO_INDEX(t INDEX33555511) */ * from DMHR.TAB01 t where t.ID=1;'; SELECT HASH_VALUE FROM SYS.V$SQLTEXT WHERE SQL_TEXT LIKE 'select /*+ NO_INDEX(t INDEX33555511) */ * from DMHR.TAB01 t where t.ID=1;'; -1226422453 SP_SET_PLN_BINDED(-1226422453,'SYSDBA', 'SQL', 2); 说明: SP_SET_PLN_BINDED( sql_text VARCHAR(32767), -- SQL语句文本(需完整匹配)或 SQL哈希值(从 `V$CACHEPLN.HASH_VALUE`或`V$SQLTEXT.HASH_VALUE` 获取) schid INTEGER, -- 模式ID(可通过 `SELECT SCHID FROM SYSOBJECTS WHERE NAME='模式名' AND TYPE$='SCH'` 获取) type VARCHAR(12), -- 语句类型:'SQL'(查询语句)或 'PL/OBJ'(存储过程/触发器) binded INTEGER -- 绑定类型:0(解绑)、1(内存绑定)、2(持久化绑定) );

4)查询系统中绑定执行计划持久化的信息。

select * from SYSPLNINFO; 1 -1226422453 150994945 7 select /*+ NO_INDEX(t INDEX33555511) */ * from DMHR.TAB01 t where t.ID=1; <二进制> 11 1 N --查询系统中绑定执行计划对应字典对象的信息。 select * from SYSPLNOBJID; 1 150995946 1 1036 1 33555510 --针对sql查询是否已添加持久化绑定 select * from v$cachepln where HASH_VALUE='-1226422453';

5)移除和禁用

移除系统表 SYSPLNINFO 中 PLN_ID 为 1 的执行计划

SP_REMOVE_STORE_PLN(1);

–禁用系统表 SYSPLNINFO 中 PLN_ID 为 1 的执行计划

SP_SET_PLN_DISABLED(1,1);--解开禁用是0

6)确认持久化计划是否生效

可以通过dmp 直接计划方式导出新的执行计划

–先确认SQL 对应的执行计划缓存号cache_item

select cache_item,sqlstr,* from v$cachepln where sqlstr like '%select /*+ NO_INDEX(t INDEX33555511) */ * from DMHR.TAB01 t where t.ID=1;%' ; 139649798914888 select /*+ NO_INDEX(t INDEX33555511) */ * from DMHR.TAB01 t where t.ID=1; 139649798914888 SQL -1226422453 150994945 50331649 0 N 0 1 1036 select /*+ NO_INDEX(t INDEX33555511) */ * from DMHR.TAB01 t where t.ID=1; 139649808224424 NULL 160 7 0 0 3 Y 56444 Y P Y N

–打印内存中的缓存计划执行以下命令,打印出缓存计划到默认路径,默认路径在数据库实例目录的trace文件夹中 –假定cache_item=139649798914888

alter session set events 'immediate trace name plndump,level 139649798914888';

欢迎访问达梦技术分享社区 ECO

https://eco.dameng.com

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/15 5:33:17

Product Hunt 每日热榜 | 2025-12-26

1. DiffSense 标语&#xff1a;本地AI Git提交生成器&#xff0c;专为Apple Silicon设计 介绍&#xff1a;DiffSense 在 Apple Silicon 上使用原生的 AFM 3B 模型 gratuitamente 生成 git 提交信息。它在本地运行&#xff0c;实现零延迟&#xff0c;确保你的代码保持私密。它…

作者头像 李华
网站建设 2026/4/12 3:16:36

ArrayList 和 LinkedList 的区别是什么?

在Java集合框架中&#xff0c;ArrayList和LinkedList都是List接口的实现类&#xff0c;但底层数据结构和操作效率存在显著差异&#xff1a;1. 底层数据结构ArrayList基于动态数组实现。初始容量为10&#xff0c;当元素超出容量时&#xff0c;自动扩容至原容量的1.5倍&#xff0…

作者头像 李华
网站建设 2026/4/15 12:03:12

八股篇(1):LocalThread、CAS和AQS

八股篇&#xff08;1&#xff09;&#xff1a;LocalThread、CAS和AQS ThreadLocal ThreadLocal 的作用 线程隔离&#xff1a;ThreadLocal 为每个线程提供了独立的变量副本&#xff0c;这意味着线程之间不会互相影响&#xff0c;可以安全地在多线程环境中使用这些变量。降低耦合…

作者头像 李华
网站建设 2026/4/11 13:40:12

【粉丝福利社】分布式系统性能优化:方法与实践

&#x1f48e;【行业认证权威头衔】 ✔ 华为云天团核心成员&#xff1a;特约编辑/云享专家/开发者专家/产品云测专家 ✔ 开发者社区全满贯&#xff1a;CSDN博客&商业化双料专家/阿里云签约作者/腾讯云内容共创官/掘金&亚马逊&51CTO顶级博主 ✔ 技术生态共建先锋&am…

作者头像 李华
网站建设 2026/4/14 22:22:01

基于PID优化和矢量控制装置的四旋翼无人机附MatlabSimulink

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。&#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室&#x1f34a;个人信条&#xff1a;格物致知,完整Matlab代码获取及仿真…

作者头像 李华
网站建设 2026/4/15 8:09:52

《国产操作系统》学习心得:DM数据库在国产系统上的实战应用

前言在数字化转型与自主可控战略深化的背景下&#xff0c;麒麟、统信等国产操作系统已广泛应用于政府、金融、能源等关键领域&#xff0c;而“国产操作系统国产数据库”的协同架构&#xff0c;是构建自主可控IT体系的核心支撑。达梦DM8作为国内主流的自主研发数据库&#xff0c…

作者头像 李华