稳定执行计划操作手册–oracle库

稳定执行计划操作手册–oracle库。稳定执行计划操作手册。

一、 概述

本文档列举了不同版本间稳定执行计划的方法,给出了详细的操作步骤。考虑到可阅读性及可操作性,未做过多的原理介绍,需要使用者在操作前已经具备相关技术知识,以便操作起来得心应手。

Outline 的使用前提

Outline的功能是为了保存sql执行计划,以保证sql在db配置或者数据变化时每次执行时都使用该执行计划。Outline的实现是通过保存生成sql 执行计划的输入信息(包括hint, 初时化参数等)。

Outline使用需要注意的事项:

1) Outline的计划只有在outline内所有hint都有效的情况下才会被使用。如:索引没有创建的前提下,索引的hint是失效的,导致整个outline计划不会被使用。

2) 参数Cursor_sharing=force时不能使用outline. 当前环境cursor_sharing =exact

3) literial sql的共享程度不高,Outline针对绑定变量的sql较好。针对literial sql的情况,需要每条sql都生成outline。或是在cursor_sharing=similar 情况下生成。但在这种情况下,

生成outline 的环境与生产环境应具有相同的cursor_sharing 参数值。

4) 创建outline需要有create any outline的权限。

二、 9i 使用方法

简述

这里描述的是在Oracle 数据库生产环境中由于未知的原因,使得单个sql出现严重的性能问题,在判断出是执行计划不正确引起的时,采用outlines 技术,从其它具有正确的执行计划的环境,

如测试库,开发库等获取正确的执行计划,并导入到生产库中的方法。

以下步骤可用SYS用户或者实名用户。

步骤一、 授权

可预先在各个数据库中以 sys 执行以下步骤,以便节省后续的时间:(这一步一般不需要处理)

— 为 outln 用户授权

grant create any outline to outln;

grant drop any outline to outln;

grant all on plan_table to outln;

— 创建 plan_table 并创建同义词

@?/rdbms/admin/utlxplan.sql;

create public synonym plan_table for plan_table;

grant select ,insert, update, delete on plan_table to public;

步骤二、 获取执行计划

在生产库获得存在性能问题的SQL的 sql_hash_value ,并且获取当前执行计划。

步骤三、 获取SQL文本

从v$sqltext 中获得相应的sql语句片段,通过UE替换成完整SQL。

除最后一行外,其它行尾部的数字一定会是64,表示该行除该数字外有64个字符,最后一行的数字也为指示该行有多少字符。通过UE替换64^p为空,再将最后的字符数替换为分号即可。

set linesize 80

set head off

set feedback off

spool /tmp/sql1.txt

select sql_text || length(sql_text) sql_text from v$sqltext where hash_value=&hash_value

order by piece;

spool off

步骤四、 生成outline

1) 找到有好的执行计划其它环境,如COW库、测试库、开发库或其它同类型的生产库。

2) 如果没有能够找到好的执行计划,需要想办法在其它环境制造出好的执行计划,如临时删除一个不合适的索引,从而强制其使用期望的索引。

通过如下SQL生成outline,红色部分需要替换:

create outline for category special on

<步骤三获取的问题SQL文本>;

步骤五、 导出outline

使用如下命令导出outline,parfile内容如下,红色部分注意替换:

exp parfile=exp_outl.par

–exp_outl.par

userid=”outln/outln”

tables=(outln.ol$,outln.ol$hints,outln.ol$nodes)

file=outln_20120627.dmp

query=”WHERE ol_name in (”,”,”)”

STATISTICS=NONE

步骤六、 传输dmp文件

通过主机命令将dmp文件传输至目标库。

步骤七、 导入outline

在目标库导入outline,命令如下,红色部分需要替换:

imp outln/outln file=outln_20120627.dmp full=y ignore=y log=ol_imp.log

步骤八、 启用outline

导入outline后,执行如下命令启用outline

exec dbms_outln.update_signatures;

alter system set use_stored_outlines=special;

步骤九、 验证outline

在生产库kill还在使用原执行计划的session,以便其重新登录后使用新计划,检查如下确认outline生效:

01. 检查dba_outlines:

select name,

to_char(TIMESTAMP, ‘yyyy-mm-dd hh24:mi:ss’) TIMESTAMP,

USED,

SQL_TEXT

from dba_outlines

where name like ‘KXN%’;

02. 检查新进的SQL是否用上好的执行计划

三、 10g 使用方法

简述

10g做outline比9i简单,不需要用UE处理SQL文本,直接拿sql_hash_value和child_number即可,实际中可以使用SYS用户和实名用户,如果用10g的方法抓到SQL是错误的,可以使用9i的方法。

步骤一、 获取SQL信息

查出问题SQL的hash_value和child_number

select hash_value,child_number from v$sql where hash_value in(‘1030675442’,

‘1165145440’,

‘2506807260’);

步骤二、 生成 outline

alter session set create_stored_outlines=true;

exec dbms_outln.create_outline(2452139749, 0, ‘SPECIAL’);

步骤三、 修改outline名称

上一步生成的outline是系统自动命名的,可将outline名称修改为有意义的名字。

alter outline SYS_OUTLINE_12062711343918532 rename to kxn_1030675442;

步骤四、 导出outline

使用如下parfile导出outline,注意替换红色部分命令如下:

exp parfile=exp_outl.par

–exp_outl.par

userid=”outln/outln”

tables=(outln.ol$,outln.ol$hints,outln.ol$nodes)

file=outln_20150927.dmp

query=”WHERE ol_name in (”,”,”)”

STATISTICS=NONE

步骤五、 传输dmp文件

通过主机命令将dmp文件传输至目标库。

步骤六、 导入outline

在目标库导入outline,命令如下,红色部分需要替换:

imp outln/outln file=outln_20150927.dmp full=y ignore=y log=ol_imp0927.log

步骤七、 启用outline

导入outline后,执行如下命令启用outline

exec dbms_outln.update_signatures;

alter system set use_stored_outlines=special;

步骤八、 验证outline

在生产库kill还在使用原执行计划的session,以便其重新登录后使用新计划,检查如下确认outline生效:

01. 检查dba_outlines:

select name,

to_char(TIMESTAMP, ‘yyyy-mm-dd hh24:mi:ss’) TIMESTAMP,

USED,

SQL_TEXT

from dba_outlines

where name like ‘LIZY%’;

02. 检查新进的SQL是否用上好的执行计划

四、 outline 互换

简述

一般通过导出导入outline可解决紧急问题,但是有一些情况,比如需要导出导入的执行计划是经过修改后的SQL得到的(比如hint),

修改后的SQL要保证和修改前的处理逻辑是一样的,返回结果是一样的,这种情况单纯的导出导入outline是不行的,需要用到outline互换。

这里前两步做outline的方法,可用9i的,如果是10g及以上,也可以用10g的方法,在互换名称的时候注意名字正确就可以。

步骤一、 优化前做outline

这一步是为原来的,性能差的执行计划生成outline。

CREATE OR REPLACE OUTLINE before for category special ON

<问题SQL文本>;

步骤二、 优化后做outline

这一步是为加Hint后的,好的执行计划生成outline。

CREATE OR REPLACE OUTLINE after for category special ON

<问题SQL文本>;

步骤三、 互换outline名字

这一步是关键,通过互换outline名字,达到交换执行计划的目的。

UPDATE OUTLN.OL$HINTS

SET OL_NAME=DECODE(OL_NAME,’after’,’before’,’before’,’after’)

WHERE OL_NAME IN (‘after’,’before’);

步骤四、 启用outline

交换完成后,执行如下命令启用outline。

exec dbms_outln.update_signatures;

alter system set use_stored_outlines=special;

步骤五、 删除无用outline

通过前面交换后,加hint后的SQL执行执行计划变成原来的较差的执行计划了,为了不影响版本下发等,将这个outline删除掉。

drop outline after;

步骤六、 修改outline名称

将前面保留下来的before修改为有意义的名字。

alter outline before rename to kxn_1030675442;

步骤七、 验证outline

在生产库kill还在使用原执行计划的session,以便其重新登录后使用新计划,检查如下确认outline生效:

01. 检查dba_outlines:

select name,

to_char(TIMESTAMP, ‘yyyy-mm-dd hh24:mi:ss’) TIMESTAMP,

USED,

SQL_TEXT

from dba_outlines

where name like ‘KXN%’;

02. 检查新进的SQL是否用上好的执行计划

五、 11g SPM使用方法

简述

11g数据库,采用SPM管理执行计划,应该优先使用SPM解决SQL执行计划问题,下面介绍常用场景下的操作方法。

场景一. 加hint优化后替换原执行计划

当在同一个数据库,既有好的执行计划,又有坏的执行计划时,采用这种方法。

步骤一、 装载坏的执行计划

获得执行计划错误的SQL语句的SQL_ID,并当前将坏的执行计划装载到SPM里。

variable cnt number;

execute :cnt :=DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE(SQL_ID => ‘&SQL_ID’, PLAN_HASH_VALUE => &HASH_VALUE) ;

步骤二、 确认被装载到SPM

检查SPM,确认相关的SQL计划已经被装载到SPM,LOAD进来的一般是最新的。

select SQL_HANDLE, PLAN_NAME, ENABLED, ACCEPTED, SQL_TEXT

from dba_SQL_PLAN_BASELINES

where ACCEPTED = ‘YES’

order by LAST_MODIFIED;

步骤三、 优化SQL

调整SQL语句,如增加新的hint,确认获得理想的执行计划后,执行调整后的语句,取得SQL_ID和Plan hash value。

select sql_id, plan_hash_value

from v$sql

where sql_text like ‘%/*+ test2-nbh INDEX(demand_state_alias%’;

注意

对于有绑定变量的SQL,最好也使用绑定变量的方式来获得正确的执行计划,如果使用字面量,执行计划虽然被装载,但可能无法被SQL语句使用。

同时可以在SQL语句增加一些特别的提示,以容易获得修改后的语句,如上面的查询增加test2-nbh这样一个标识。

(0)
上一篇 2022年3月22日
下一篇 2022年3月22日

相关推荐