oracle通过sql patch 为sql语句加hint
有时候,sql 语句执行计划选择错误我们可以通过hint 方式更正执行计划,但是添加hint需要调整sql意味着需要对程序代码进行改动,这对一些生产环境可能是不允许的。从11g开始,可以通过sql patch 不改动sql语句为sql增加hint从而达到优化的目的。
对于绑定变量sql,可以采用如下方式:
11g:
--创建sql patch
declare
c clob;
hint_text varchar2(4000);
begin
select sql_fulltext into c from gv$sql where sql_id='&sql_id' and rownum=1;
hint_text:='&hint’ ;
sys.dbms_sqldiag_internal.i_create_patch
(sql_text => c,
hint_text => hint_text,
name => 'sql_patch_&sql_id');
end;
/
12c以及以上:
--创建sql patch
declare
hint_text varchar2(4000);
begin
hint_text:='&hint' ;
sys.dbms_sqldiag_internal.i_create_patch
(sql_id =>’&sql_id’,
hint_text => hint_text,
creator=>'SYS',
name => 'sql_patch_&sql_id');
end;
/
--删除sql patch
begin
dbms_sqldiag.drop_sql_patch (name=> 'sql_patch_&sql_id');
end;
/
--禁用sql patch
begin
dbms_sqldiag.alter_sql_patch(name=>'sql_patch_&sql_id', attribute_name=>'status', value=>'disabled');
end;
/
对于动态sql,可以采用如下方式:
--创建sql patch
DECLARE
sql_fulltext clob;
hints varchar2(4000) :='&hints';
descriptions varchar2(100):='sql patch for sql &sql_id';
names varchar2(100) :='sql_patch_&sql_id';
output varchar2(100);
sqlpro_attr SYS.SQLPROF_ATTR;
BEGIN
sqlpro_attr := SYS.SQLPROF_ATTR(hints);
select sql_fulltext into sql_fulltext from gv$sql where sql_id='&sql_id' and rownum=1;
output := SYS.DBMS_SQLTUNE_INTERNAL.I_CREATE_SQL_PROFILE(
SQL_TEXT => sql_fulltext,
PROFILE_XML => DBMS_SMB_INTERNAL.VARR_TO_HINTS_XML(sqlpro_attr),
NAME => names,
DESCRIPTION => descriptions,
CATEGORY => 'DEFAULT',
CREATOR => 'SYS',
VALIDATE => TRUE,
TYPE => 'PATCH',
FORCE_MATCH => TRUE,
IS_PATCH => TRUE);
dbms_output.put_line(output);
END;
/
一些例子:
1、监控指定sql 性能,添加MONITOR hint
declare
c clob;
hint_text varchar2(4000);
begin
select sql_fulltext into c from gv$sql where sql_id='&sql_id' and rownum=1;
hint_text:='MONITOR’ ;
sys.dbms_sqldiag_internal.i_create_patch
(sql_text => c,
hint_text => hint_text,
name => 'sql_patch_&sql_id');
end;
/
2、在acs 特性关闭的情况下,解决由于列数据分布倾斜绑定变量窥视导致的sql 执行性能问题,添加BIND_AWARE hint
declare
c clob;
hint_text varchar2(4000);
begin
select sql_fulltext into c from gv$sql where sql_id='&sql_id' and rownum=1;
hint_text:='BIND_AWARE’ ;
sys.dbms_sqldiag_internal.i_create_patch
(sql_text => c,
hint_text => hint_text,
name => 'sql_patch_&sql_id');
end;
/
3、在基数估计不准确的情况下,解决由于MERGE JOIN CARTESIAN 导致的性能问题,添加OPT_PARAM('_optimizer_mjc_enabled','false') hint
declare
c clob;
hint_text varchar2(4000);
begin
select sql_fulltext into c from gv$sql where sql_id='&sql_id' and rownum=1;
hint_text:='OPT_PARAM(''_optimizer_mjc_enabled'',''false'')' ;
sys.dbms_sqldiag_internal.i_create_patch
(sql_text => c,
hint_text => hint_text,
name => 'sql_patch_&sql_id');
end;
/
4、sql 性能故障诊断时,查看sql 运行时的统计信息,添加 GATHER_PLAN_STATISTICS hint
declare
c clob;
hint_text varchar2(4000);
begin
select sql_fulltext into c from gv$sql where sql_id='&sql_id' and rownum=1;
hint_text:='GATHER_PLAN_STATISTICS’;
sys.dbms_sqldiag_internal.i_create_patch
(sql_text => c,
hint_text => hint_text,
name => 'sql_patch_&sql_id');
end;
/
5、sql 执行计划走指定的索引,添加 INDEX(TABLE_NAME INDEX_NAME) hint
declare
c clob;
hint_text varchar2(4000);
begin
select sql_fulltext into c from gv$sql where sql_id='&sql_id' and rownum=1;
hint_text:='INDEX(TABLE_NAME INDEX_NAME)’;
sys.dbms_sqldiag_internal.i_create_patch
(sql_text => c,
hint_text => hint_text,
name => 'sql_patch_&sql_id');
end;
/
sql patch 查看:
select t.name,t.sql_text,t.status,t.description,t.force_matching from dba_sql_patches t
本文来自博客园,作者:踏雪无痕2017,转载请注明原文链接:https://www.cnblogs.com/oradba/p/15661058.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)