阿里巴巴数据库操作手册 20-固定执行计划-sqlprofile

V1.0

 

Revision

Author/Modifier Comments

No.

Date

1.0 2012-02 魏兴华 初稿
       

一、 目的

在遭遇执行计划不稳定或者执行计划错误的情况下,通过sql profile来固定SQL执行计划以确保执行计划稳定性以及提高性能。sql profile相对于outline,baseline使用简单方便。可以实现outline,baseline的一切功能。使用@profile脚本,只需要提供sql_id,hint就可以起到固定执行计划的作用。

二、 适用范围

l 由于sql profile对于固化执行计划操作起来非常的迅速方便,因此对于执行计划突然走错,数据库压力飙升的情况,建议使用sql profile来修改固定执行计划。而outline和baseline相对来说,操作要复杂的多。sql profile是oracle 10G提供的一个功能。

l 对于执行计划走错,但是又来不及发布修改后的SQL,可以暂时通过sql profile 来修正执行计划,等应用发布后,再做删除。

l 需要注意的是,sql profile所接受的hint需要包含query block。因此dba需要具备query block的知识。

l sql profile是依赖sql文本进行匹配的,这意味着一份sql profile可能同时被用于两张有相同名称但分属于不同schema下的表,使用前需要确认。

三、 风险评估

l sql profile是针对sql 文本的,文本不区分大小写,空格,如果文本被修改,那么 sql profile就会不起作用。因此如果多个schema下有同样的sql语句,那么创建的sql profile将对他们都会生效。因此,请确认这种情况是否可以发生。如果不允许发生,那么需要确保不同schema下的sql文本不一样

l 在做数据迁移过程中,如果原系统中存在已经建立过的sql profile,请不要在数据迁移过程中忘记在新系统中安装他们。

l 需要注意,表对象被删除时,sql profile并不会被删除,当然这个应该也不是很严重的问题。如果想要删除sql profile,必须采取显式的删除。

四、 操作流程

1. 准备工作

a) 建议采用system用户来创建,修改,删除sql profile。创建、修改、删除sql profile的用户需要具有create any sql sprofile,alter any sql profile,drop any sql profile的权限。到oracle 11G,不再建议使用上面这3个系统权限,建议使用administer sql management object的系统权限。

b) 找出需要修改sql的sql 文本

2. 执行过程

我们以如下查询为例。object_id列上存在索引。查询默认的执行计划走了 object_i列上的索引。

select count(*) from wxh_tbd where object_id=:a

我们可能对于这个查询计划的固化有两种需求:

1)想继续用走索引的执行计划,为确保执行计划不走错,通过sql profile来固化执行计划。步骤如下:

declare

v_hints sys.sqlprof_attr;

begin

———-HINT部分

v_hints := sys.sqlprof_attr(’IND(WXH_TBD@SEL$1 WT_OI_IND)’);

———-SQL语句部分

dbms_sqltune.import_sql_profile(’select count(*) from wxh_tbd where object_id=:a’,

v_hints,

—————-PROFILE 的名字

‘SQLPROFILE_NAME3′,

force_match => true);

end;

/

2)不想用走索引的执行计划,想让执行计划走全表扫描。可以通过如下方式操作:

declare
v_hints sys.sqlprof_attr;
begin
v_hints := sys.sqlprof_attr(’full(wxh_tbd@sel$1)’);———-HINT部分
dbms_sqltune.import_sql_profile(’select count(*) from wxh_tbd where object_id=:a’,———-SQL语句部分
v_hints,
‘SQLPROFILE_NAME3′,——————————–PROFILE 的名字
force_match => true);
end;
/

除了上面介绍的方式来使用sql profile,你还可以通过我提供的脚本@profile来进行创建 sql profile。这个脚本的使用方法很简单。你只需要提供sql_id和hint就可以了。由于sql profile的hint需要指定query block,因此需要dba具备查询块的相关知识。@profile的脚本给你提供了原始执行计划的query block供你参考,绝大多数时候,这些已经能够提供给你需要的query block的name了。@profile脚本里的hint可以接受多个hint,之间用空格隔开就可以了。例如:

full(@”SEL$1″ “WXH_TBD”@”SEL$1″)  full(@”SEL$2″ “T”@”SEL$2″)

3. 验证方案

explain plan for

select count(*) from wxh_tbd where object_id=:a;

 

Execution Plan

———————————————————-

Plan hash value: 853361775

 

—————————————————————————

| Id  | Operation          | Name    | Rows  | Bytes | Cost (%CPU)| Time     |

—————————————————————————

|   0 | SELECT STATEMENT   |         |     1 |    13 |   144   (3)| 00:00:01 |

|   1 |  SORT AGGREGATE    |         |     1 |    13 |            |          |

|*  2 |   TABLE ACCESS FULL| WXH_TBD |   198 |  2574 |   144   (3)| 00:00:01 |

————————————————————————–

Note

—–

- SQL profile “SQLPROFILE_NAME3″ used for this statement

从note部分我们看到sql profile已经 起作用了

五、 核心对象风险

理论上sql profile影响到的只是一条特定的SQL,因此相对风险比较低.对于核心表对象上sql profile的创建最好放到业务低峰期操作。

六、 回退方案

exec dbms_sqltune.drop_sql_profile(’ SQLPROFILE_NAME3′);

七、 历史故障及教训

  1. da shang
    donate-alipay
               donate-weixin weixinpay

发表评论↓↓