达梦数据库提供无需修改 SQL 语句但依然能按照指定的 HINT 运行语句的相关功能。
使用时有以下限制:
- INI 参数 ENABLE_INJECT_HINT 需设置为 1;
- SQL 只能是语法正确的增删改查语句;
- SQL 会经过系统格式化,格式化之后的 SQL 和指定的规则名称必须全局唯一;
- HINT 一指定,则全局生效;
- 系统检查 SQL 匹配时,必须是整条语句完全匹配,不能是语句中子查询匹配;
- 可通过 SYSINJECTHINT 视图查看已指定的 SQL 语句和对应的 HINT。
1)SF_INJECT_HINT
定义:
SF_INJECT_HINT (
sql_text text,
hint_text text,
name varchar(128),
description varchar(256),
validate boolean
)
或者
SF_INJECT_HINT (
sql_text text,
hint_text text,
name varchar(128),
description varchar(256),
validate boolean,
fuzzy boolean
)
功能说明:
对指定 SQL 增加 HINT。
参数说明:
sql_text: 要指定 HINT 的 SQL 语句。
hint_text:要为 SQL 指定的 HINT。
name:可以指定名称,或者设为 NULL 让系统自动创建名称。
description: 对规则的详细描述,可为 NULL。
validate:规则是否生效,可为 NULL,则为默认值 TRUE。
fuzzy:SQL 的匹配规则为精准匹配或模糊匹配。值为 TRUE 或 NULL 时,模糊匹配;
值为 FALSE 或缺省时,精准匹配。
返回值:
执行成功返回名称,执行失败报错误信息。
2)SF_DEINJECT_HINT
定义:
SF_DEINJECT_HINT (
name varchar(128)
)
功能说明:
对指定 SQL 撤回已增加的 HINT。
参数说明:
name: 要删除的规则名称。
返回值:
执行成功返回 0,执行失败返回错误码。
- SF_ALTER_HINT
定义:
INT
SF_ALTER_HINT (
name
varchar(128),
attribute_name varchar(12),
attribute_value varchar(256)
)
功能说明:
修改已指定 HINT 的规则属性。
参数说明:
name: 要修改的规则名称。
attribute_name: 要修改的属性名。
attribute_value:设置的属性值。
支持的可修改的属性名和属性值包括:属性名 NAME,属性值为修改后的规则名;属性
名 DESCRIPTION ,属性值为修改后的规则描述;属性名 STATUS , 属 性 值 为
ENABLED/DISABLED。
返回值:
执行成功返回 0,执行失败返回错误码。
测试验证情况如下:
1.绑定hint参数
--新建测试表
SQL> create table test(id int,info varchar);
操作已执行
--插入测试数据
SQL> insert into test select level,'a' from dual connect by level <=10000;
影响行数 10000
--创建索引,更新统计信息
SQL> create index idx_test_id on test(id);
操作已执行
SQL> stat 100 on test(id);
操作已执行
--查看执行计划
SQL> explain select * from test where id>1; --正常是走全表扫描
1 #NSET2: [1, 9999, 60]
2 #PRJT2: [1, 9999, 60]; exp_num(3), is_atom(FALSE)
3 #SLCT2: [1, 9999, 60]; TEST.ID > 1
4 #CSCN2: [1, 10000, 60]; INDEX33555470(TEST)
--修改ENABLE_INJECT_HINT参数
SQL> sp_set_para_value(1,'ENABLE_INJECT_HINT',1); --开启ENABLE_INJECT_HINT参数
DMSQL 过程已成功完成
--绑定hint参数
SQL> SF_INJECT_HINT('select * from test where id>1;','INDEX(TEST,IDX_TEST_ID)','INJECT1','test injecting hint', TRUE,TRUE);指定该语句使用IDX_TEST_ID索引
DMSQL 过程已成功完成
--再次检查执行计划
SQL> explain select * from test where id>1; --再次查询走了索引
1 #NSET2: [10, 9999, 60]
2 #PRJT2: [10, 9999, 60]; exp_num(3), is_atom(FALSE)
3 #BLKUP2: [10, 9999, 60]; IDX_TEST_ID(TEST)
4 #SSEK2: [10, 9999, 60]; scan_type(ASC), IDX_TEST_ID(TEST), scan_range(1,max]
--检查hint绑定信息
SQL> select * from SYSINJECTHINT;
行号 NAME DESCRIPTION VALIDATE SQL_TEXT HINT_TEXT CREATOR
---------- ------- ------------------- -------- ------------------------------ ----------------------- -------
CRTDATE INFO1 INFO2 INFO3
-------------------------- ----------- ---------- ----------
1 INJECT1 test injecting hint TRUE select * from test where id>1; INDEX(TEST,IDX_TEST_ID) SYSDBA
2023-12-04 17:11:22.437000 1 NULL NULL
已用时间: 14.008(毫秒). 执行号:2800.
SQL>
2.取消hint绑定
--取消hint绑定
SQL> SF_DEINJECT_HINT('INJECT1');
DMSQL 过程已成功完成
已用时间: 2.713(毫秒). 执行号:2802.
SQL> select * from SYSINJECTHINT;
未选定行
已用时间: 0.666(毫秒). 执行号:2803.
SQL> explain select * from test where id>1;
1 #NSET2: [1, 9999, 64]
2 #PRJT2: [1, 9999, 64]; exp_num(3), is_atom(FALSE)
3 #SLCT2: [1, 9999, 64]; TEST.ID > 1
4 #CSCN2: [1, 10000, 64]; INDEX33555773(TEST)
已用时间: 6.247(毫秒). 执行号:0.
SQL>
3.修改指导hint属性规则
--修改hint规则属性
SQL> select NAME, VALIDATE from SYSINJECTHINT;
行号 NAME VALIDATE
---------- ------- --------
1 INJECT1 TRUE
已用时间: 0.632(毫秒). 执行号:2810.
SQL> SF_ALTER_HINT('INJECT1', 'STATUS', 'DISABLED');
DMSQL 过程已成功完成
已用时间: 1.153(毫秒). 执行号:2811.
SQL> select NAME, VALIDATE from SYSINJECTHINT;
行号 NAME VALIDATE
---------- ------- --------
1 INJECT1 FALSE
已用时间: 0.538(毫秒). 执行号:2812.
SQL> explain select * from test where id>1;
1 #NSET2: [1, 9999, 64]
2 #PRJT2: [1, 9999, 64]; exp_num(3), is_atom(FALSE)
3 #SLCT2: [1, 9999, 64]; TEST.ID > 1
4 #CSCN2: [1, 10000, 64]; INDEX33555773(TEST)
已用时间: 6.211(毫秒). 执行号:0.
SQL>