在达梦数据库中,HINT注入是一种高级优化技术,允许在不修改SQL语句的情况下,通过外部配置为查询添加 HINT,从而优化查询性能。enable_inject_hint 是一个用于控制是否启用SQL语句中Hint提示注入的功能参数。sf_inject_hint 是一个与HINT注入相关的系统函数,用于动态为SQL语句添加HINT以优化查询性能。
1、HINT注入的作用
HINT注入功能允许DBA在不修改应用程序代码的情况下,为特定SQL语句动态添加HINT。这在以下场景中非常有用:
(1)无法直接修改 SQL 语句(例如第三方应用程序)。
(2)需要临时调整查询执行计划以解决性能问题。
(3)在测试环境中验证不同 HINT 的效果。
2、enable_inject_hint参数
参数名称:enable_inject_hint
作用:控制是否启用 HINT 注入功能。
1:启用 HINT 注入。
0:禁用 HINT 注入(默认值)。
3、查看当前设置
可以通过以下SQL语句查看enable_inject_hint的当前值:
SHOW PARAMETER 'enable_inject_hint';
4、修改设置
可以通过以下SQL语句修改enable_inject_hint的值:
- 启用 Hint 注入:ALTER SYSTEM SET 'enable_inject_hint' = 1;- 禁用 Hint 注入:ALTER SYSTEM SET 'enable_inject_hint' = 0;
5、配置 HINT 注入规则
通过达梦数据库的HINT注入功能,可以为特定的SQL语句动态添加HINT。通常需要配置以下内容:
sf_inject_hint 的语法通常如下:sf_inject_hint(sql_fingerprint, hint_text);sql_fingerprint:目标 SQL 语句的指纹(唯一标识),可以是SQL语句的文本或哈希值。hint_text:需要注入的 HINT 内容。例如:sf_inject_hint('SELECT * FROM emp WHERE emp_id = ?', 'INDEX(emp emp_id_idx)');
6、验证 HINT 注入效果
执行目标SQL语句,并通过EXPLAIN或性能监控工具确认HINT是否生效。
7、实验示例
(1)创建测试表与测试数据
create table test as select * from dba_objects;insert into test select * from test;执行多次插入SQL> select count(*) from test;LINEID COUNT(*)---------- --------------------1 1099776
(2)创建索引
create index idx_status on test(status);
(3)收集单表统计信息
BEGINDBMS_STATS.GATHER_TABLE_STATS(ownname => 'SYSDBA',tabname => 'TEST',estimate_percent => 100,method_opt => 'FOR ALL COLUMNS SIZE AUTO');END;/
(4)查看优化前执行计划(CSCN2:聚集索引全表扫描表)
explain select owner from test where STATUS='VALID' and object_name='##PLAN_TABLE';SQL> explain select owner from test where STATUS='VALID' and object_name='##PLAN_TABLE';1 #NSET2: [322, 2046, 156]2 #PRJT2: [322, 2046, 156]; exp_num(2), is_atom(FALSE)3 #SLCT2: [322, 2046, 156]; (TEST.STATUS = 'VALID' AND TEST.OBJECT_NAME = '##PLAN_TABLE')4 #CSCN2: [322, 2199552, 156]; INDEX33555474(TEST); btr_scan(1)used time: 1.388(ms). Execute id is 0.
(5)使用hint提示调整执行计划( SSEK2 索引扫描)
explain select /*+ INDEX(test idx_status) */ owner from test where STATUS='VALID' and object_name='##PLAN_TABLE';SQL> explain select /*+ INDEX(test idx_status) */ owner from test where STATUS='VALID' and object_name='##PLAN_TABLE';1 #NSET2: [2605, 2046, 156]2 #PRJT2: [2605, 2046, 156]; exp_num(2), is_atom(FALSE)3 #SLCT2: [2605, 2046, 156]; TEST.OBJECT_NAME = '##PLAN_TABLE'4 #BLKUP2: [2605, 2197504, 156]; IDX_STATUS(TEST)5 #SSEK2: [2605, 2197504, 156]; scan_type(ASC), IDX_STATUS(TEST), scan_range['VALID','VALID'], is_global(0)used time: 2.092(ms). Execute id is 0.
(6)INJECT HINT函数使用示例(模糊匹配)
sf_inject_hint(sql_text => 'select owner from test where STATUS=',hint_text =>'index(test,idx_status)',name =>'TEST_INDEX',description => 'this is a test join hint.',validate => true,fuzzy => true);
使用HINT的INI参数可通过V$HINT_INI_INFO 动态视图查询。
(7)验证 HINT 注入效果( SSEK2 索引扫描)
执行目标 SQL 语句,并通过 EXPLAIN 或性能监控工具确认 HINT 已生效(序号5走索引查询)。
explain select owner from test where STATUS='VALID' and object_name='##PLAN_TABLE';SQL> explain select owner from test where STATUS='VALID' and object_name='##PLAN_TABLE';1 #NSET2: [2605, 2046, 156]2 #PRJT2: [2605, 2046, 156]; exp_num(2), is_atom(FALSE)3 #SLCT2: [2605, 2046, 156]; TEST.OBJECT_NAME = '##PLAN_TABLE'4 #BLKUP2: [2605, 2197504, 156]; IDX_STATUS(TEST)5 #SSEK2: [2605, 2197504, 156]; scan_type(ASC), IDX_STATUS(TEST), scan_range['VALID','VALID'], is_global(0)used time: 1.625(ms). Execute id is 0.
(8)INJECT HINT设置查看
查询SYSINJECTHINT视图可以查看已指定的SQL语句和对应的HINT:
select NAME, DESCRIPTION, VALIDATE, SQL_TEXT, HINT_TEXT, CREATOR, CRTDATE from SYSINJECTHINT;LINEID NAME DESCRIPTION VALIDATE SQL_TEXT HINT_TEXT CREATOR CRTDATE---------- ---------- ------------------------- -------- ------------------------------------ ---------------------- ------- --------------------------1 TEST_INDEX this is a test join hint. TRUE select owner from test where STATUS= index(test,idx_status) SYSDBA 2025-02-02 00:13:16.314089used time: 1.336(ms). Execute id is 1422.
(9)INJECT HINT状态修改
使用SF_ALTER_HINT函数可以设置INJECT HINT无效,置为无效后,相关的sql hint将不再生效。
SF_ALTER_HINT('TEST_INDEX' ,'STATUS', 'DISABLED');
(10)INJECT HINT设置删除
SF_DEINJECT_HINT函数可以将设置INJECT hint删除。
sf_deinject_hint('TEST_INDEX');
8、参考链接




