PLSQL_性能优化系列18_Oracle Explain Plan解析计划通过Baseline绑定

简介: 2015-05-28 Created By BaoXinjian 一、摘要 1. 应用场景 当运行很久的Job突然出现性能问题时,并排除数据量突然变大,可能原因有执行的脚本的某些对应的SQL的解析计划变更 2.

2015-05-28 Created By BaoXinjian

一、摘要


1. 应用场景

当运行很久的Job突然出现性能问题时,并排除数据量突然变大,可能原因有执行的脚本的某些对应的SQL的解析计划变更

2. 解决步骤

Step1. 通过对应的User或者其他信息查找Session ID

Step2. 通过Session_ID查看该SQL_ID历史的解析计划变换 

Step3. 如果最近发生解析计划变更,并导致效率变慢,通过SPM绑定之前的解析计划 

Step4. 确定解析计划是否绑定 

Step5. 如果脚本还在运行,让客户停掉脚本,并重新运行,以测试绑定的新的解析计划是否满足期望 

Step6. 如果绑定的解析计划并不能解决性能问题,验证后将其删除

 

二、步骤


Step1. 通过对应的User或者其他信息查找Session ID

select sql_id, username, osuser, machine, program
  from v$session
 where username = 'gavin'

Step2. 查看该SQL_ID历史的解析计划变换

select distinct a.instance_number,
                trunc(b.begin_interval_time, 'mi'),
                sql_id,
                plan_hash_value
  from dba_hist_sqlstat a, dba_hist_snapshot b
 where a.snap_id = b.snap_id
   and sql_id = '089dbukv1aanh'
 order by 2, 1

Step3. 如果最近发生解析计划变更,并导致效率变慢,通过SPM绑定之前的解析计划 (脚本coe_xfr_sql_baseline.sql)

SQL>@D:\Gavin\coe_xfr_sql_baseline.sql

Parameter 1:
SQL_ID (required)

Enter value for 1: 089dbukv1aanh


SNAP_DATE       SQL_ID             PLAN_HASH_VALUE
--------------- ------------- --------------------
2015/05/20      089dbukv1aanh           1388734953
2015/05/21      089dbukv1aanh           1388734953
2015/05/22      089dbukv1aanh           1388734953
2015/05/23      089dbukv1aanh           1388734953
2015/05/24      089dbukv1aanh           1388734953
2015/05/25      089dbukv1aanh           1388734953
2015/05/26      089dbukv1aanh           1388734953
2015/05/27      089dbukv1aanh           1388734953
2015/05/28      089dbukv1aanh           1388734953

Parameter 2:
PLAN_HASH_VALUE (required)

Enter value for 2: 1388734953

Values passed to coe_xfr_sql_baseline:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SQL_ID: "089dbukv1aanh"
PLAN_HASH_VALUE: "1388734953"

SQL>SET ECHO OFF;
SQL tuning set SS_089dbukv1aanh_1388734953 created.

SQLSET_NAME                    SQLSET_OWNER                   SQL_ID                              PLAN_HASH_VALUE
------------------------------ ------------------------------ ------------------------------ -------
SS_089dbukv1aanh_1388734953    GAVIN                          089dbukv1aanh                            1388734953
Plans Loaded: 1
sys_sql_handle: "SYS_SQL_70445f05461a3cd3"
sys_plan_name: "SQL_PLAN_70j2z0p31ng6m125daea2"
1 plan(s) modified description: "SQL_ID: 089DBUKV1AANH PLAN HASH VALUE: 1388734953 CREATED BY COE_XF
SQL tuning set SS_089dbukv1aanh_1388734953 dropped.
SQL>REM
SQL>REM SQL Plan Baseline
SQL>REM ~~~~~~~~~~~~~~~~~
SQL>REM
SQL>SELECT signature, sql_handle, plan_name, enabled, accepted, fixed--, reproduced (avail on 11.2.0
  2    FROM dba_sql_plan_baselines WHERE plan_name = :plan_name;

           SIGNATURE SQL_HANDLE                     PLAN_NAME                      ENA ACC FIX
-------------------- ------------------------------ ------------------------------ --- --- ---
 8089695306919853267 SYS_SQL_70445f05461a3cd3       SQL_PLAN_70j2z0p31ng6m125daea2 YES YES YES
SQL>
SQL>col description for a100
SQL>SELECT description
  2    FROM dba_sql_plan_baselines WHERE plan_name = :plan_name;

DESCRIPTION
----------------------------------------------------------------------------------------------------
SQL_ID: 089DBUKV1AANH PLAN HASH VALUE: 1388734953 CREATED BY COE_XFR_SQL_BASELINE.SQL
SQL>SET ECHO OFF;


coe_xfr_sql_baseline completed. 

Step4. 确定解析计划是否绑定

select sql_handle, plan_name, sql_text, creator, description, enabled, accepted, fixed
  from dba_sql_plan_baselines
 where description like '%089dbukv1aanh%'

Step5. 如果脚本还在运行,让客户停掉脚本,并重新运行,以测试绑定的新的解析计划是否满足期望

alter system disconnect session '102,102' immediate; 

Step6. 如果绑定的解析计划并不能解决性能问题,验证后将其删除

declare
  l_plan number;
begin
  l_plan := dbms_spm.drop_sql_plan_baseline('SYS_SQL_70445f05461a3cd3', 'SQL_PLAN_70j2z0p31ng6m125daea2');
  dbms_output.put_line('l_pan=' || l_plan);
end;

 

三、代码


Oracle Metalink下载代码 - ce_xfr_sql_baseline.sql

SPO coe_xfr_sql_baseline.log;
SET DEF ON TERM OFF ECHO ON FEED OFF VER OFF HEA ON LIN 2000 PAGES 100 LONG 8000000 LONGC 800000 TRIMS ON TI OFF TIMI OFF SERVEROUT ON SIZE 1000000 NUM 20 SQLP SQL>;
SET SERVEROUT ON SIZE UNL;
REM
REM Created according to coe_load_sql_baseline.sql and MOS note 789888.1 2013/06/10
REM
REM AUTHOR
REM   gavin.bao
REM
REM SCRIPT
REM   coe_xfr_sql_baseline.sql
REM
REM DESCRIPTION
REM   This script loads a plan from AWR into the SQL
REM   Plan Baseline of the specified SQL.
REM
REM PRE-REQUISITES
REM   1. Have in AWR the text for the specified SQL.
REM
REM PARAMETERS
REM   1. SQL_ID (required)
REM   2. PLAN_HASH_VALUE in AWR (required)
REM
REM EXECUTION
REM   1. Connect into SQL*Plus as user with access to data dictionary
REM      and privileges to create SQL Plan Baselines. Do not use SYS.
REM   2. Execute script coe_xfr_sql_baseline.sql passing first two
REM      parameters inline or until requested by script.
REM
REM EXAMPLE
REM   # sqlplus system
REM   SQL> START coe_xfr_sql_baseline.sql gnjy0mn4y9pbm b8f3mbkd8bkgh
REM   SQL> START coe_xfr_sql_baseline.sql;
REM
REM NOTES
REM   1. This script works on 11g or higher.
REM   2. For a similar script for 10g use coe_xfr_sql_profile.sql,
REM      which uses custom SQL Profiles instead of SQL Baselines.
REM   3. For possible errors see coe_xfr_sql_baseline.log
REM   4. Use a DBA user but not SYS. Do not connect as SYS as the staging
REM      table cannot be created in SYS schema and you will receive an error:
REM      ORA-19381: cannot create staging table in SYS schema
REM
SET TERM ON ECHO OFF;
PRO
PRO Parameter 1:
PRO SQL_ID (required)
PRO
DEF sql_id = '&1';
PRO
col SNAP_DATE for a15
select distinct to_char(trunc(b.BEGIN_INTERVAL_TIME),'yyyy/mm/dd') SNAP_DATE,SQL_ID,PLAN_HASH_VALUE
from dba_hist_sqlstat a,dba_hist_snapshot b
where SQL_ID=TRIM('&&sql_id.')
and a.snap_id=b.snap_id order by 1;
PRO
PRO Parameter 2:
PRO PLAN_HASH_VALUE (required)
PRO
DEF plan_hash_value = '&2';
PRO
PRO Values passed to coe_xfr_sql_baseline:
PRO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PRO SQL_ID: "&&sql_id."
PRO PLAN_HASH_VALUE: "&&plan_hash_value."
PRO
WHENEVER SQLERROR EXIT SQL.SQLCODE;
SET TERM OFF ECHO ON;

-- trim parameters
COL sql_id NEW_V sql_id FOR A30;
COL plan_hash_value NEW_V plan_hash_value FOR A30;
SELECT TRIM('&&sql_id.') sql_id, TRIM('&&plan_hash_value.') plan_hash_value FROM DUAL;

-- open log file
SPO coe_xfr_sql_baseline_&&sql_id..log;
GET coe_xfr_sql_baseline.log;
.

-- get user
COL connected_user NEW_V connected_user FOR A30;
SELECT USER connected_user FROM DUAL;

VAR sql_text CLOB;
VAR plan_name VARCHAR2(30);
VAR b_snap_id NUMBER;
VAR e_snap_id NUMBER;
VAR ss_name VARCHAR2(100);
EXEC :sql_text := NULL;
EXEC :plan_name := NULL;
EXEC :b_snap_id := NULL;
EXEC :e_snap_id := NULL;
EXEC :ss_name := 'SS_'||TRIM('&&sql_id.')||'_'||TRIM('&&plan_hash_value.');

-- get sql_text from awr
BEGIN
    SELECT REPLACE(sql_text, CHR(00), ' ')
      INTO :sql_text
      FROM dba_hist_sqltext
     WHERE sql_id = TRIM('&&sql_id.')
       AND sql_text IS NOT NULL
       AND ROWNUM = 1;
EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('getting sql_text from awr: '||SQLERRM);
    :sql_text := NULL;
END;
/

-- sql_text as found
SELECT :sql_text FROM DUAL;

-- check is sql_text for sql is available
SET TERM ON;
SET ECHO OFF;
BEGIN
  IF :sql_text IS NULL THEN
    RAISE_APPLICATION_ERROR(-20100, 'SQL_TEXT for SQL_ID &&sql_id. was not found in AWR (dba_hist_sqltext).');
  END IF;
END;
/


-- get snap id
DECLARE
  l_count NUMBER;
BEGIN
  SELECT min(SNAP_ID), max(SNAP_ID)
    INTO :b_snap_id, :e_snap_id
    FROM dba_hist_sqlstat
   WHERE sql_id = TRIM('&&sql_id.')
     AND plan_hash_value = TO_NUMBER(TRIM('&&plan_hash_value.'));

   IF (:b_snap_id is null or :e_snap_id is null) THEN
     RAISE_APPLICATION_ERROR(-20110, 'PHV &&plan_hash_value. for SQL_ID &&sql_id. was not be found in AWR (dba_hist_sqlstat).');
   END IF;
END;
/


DECLARE
  --ss_name VARCHAR2(100) default 'SS_'||TRIM('&&sql_id.')||'_'||TRIM('&&plan_hash_value.');
  baseline_ref_cursor DBMS_SQLTUNE.SQLSET_CURSOR;
BEGIN
  -- create sql_plan_baseline for sql using plan from AWR
  DBMS_SQLTUNE.CREATE_SQLSET(:ss_name);
  open baseline_ref_cursor for
  select VALUE(p) from
  table(DBMS_SQLTUNE.SELECT_WORKLOAD_REPOSITORY(:b_snap_id, :e_snap_id,
                                                'sql_id='||CHR(39)||TRIM('&&sql_id.')||CHR(39)||
                                                ' and plan_hash_value='||TRIM('&&plan_hash_value.'),
                                                NULL,NULL,NULL,NULL,NULL,NULL,'ALL')) p;
  DBMS_SQLTUNE.LOAD_SQLSET(:ss_name, baseline_ref_cursor);
  DBMS_OUTPUT.PUT_LINE('SQL tuning set '||:ss_name||' created.');
END;
/


-- display details of the SQL tuning set
col PLAN_HASH_VALUE clear
select SQLSET_NAME,SQLSET_OWNER,SQL_ID,PLAN_HASH_VALUE from dba_sqlset_statements where sqlset_name = :ss_name ;

-- load the plan from SQL tuning set into baseline
declare
  plans NUMBER;
  description VARCHAR2(500);
  sys_sql_handle VARCHAR2(30);
  sys_plan_name VARCHAR2(30);
begin
  plans := dbms_spm.load_plans_from_sqlset(sqlset_name => :ss_name,
                                              sqlset_owner => USER,
                                              fixed => 'YES',
                                              enabled => 'YES');
  commit;
  DBMS_OUTPUT.PUT_LINE('Plans Loaded: '||plans);

  -- find handle and plan_name for sql_plan_baseline just created
  SELECT sql_handle, plan_name
    INTO sys_sql_handle, sys_plan_name
    FROM dba_sql_plan_baselines
   WHERE creator = USER
     AND origin = 'MANUAL-LOAD'
     AND created = ( -- past 1 minute only
  SELECT MAX(created) max_created
    FROM dba_sql_plan_baselines
   WHERE creator = USER
     AND origin = 'MANUAL-LOAD'
     AND created > SYSDATE - (1/24/60));
  DBMS_OUTPUT.PUT_LINE('sys_sql_handle: "'||sys_sql_handle||'"');
  DBMS_OUTPUT.PUT_LINE('sys_plan_name: "'||sys_plan_name||'"');

  :plan_name := sys_plan_name;

  -- update description of new sql_plan_baseline
  description := UPPER('SQL_ID: '||TRIM('&&sql_id.')||' Plan Hash Value: '||TRIM('&&plan_hash_value.')||' created by coe_xfr_sql_baseline.sql');
  plans :=
  DBMS_SPM.ALTER_SQL_PLAN_BASELINE (
    sql_handle      => sys_sql_handle,
    plan_name       => sys_plan_name,
    attribute_name  => 'description',
    attribute_value => description );
  DBMS_OUTPUT.PUT_LINE(plans||' plan(s) modified description: "'||description||'"');

  DBMS_SQLTUNE.DROP_SQLSET(:ss_name);
  DBMS_OUTPUT.PUT_LINE('SQL tuning set '||:ss_name||' dropped.');
end;
/


-- display details of new sql_plan_baseline
SET ECHO ON;
REM
REM SQL Plan Baseline
REM ~~~~~~~~~~~~~~~~~
REM
SELECT signature, sql_handle, plan_name, enabled, accepted, fixed--, reproduced (avail on 11.2.0.2)
  FROM dba_sql_plan_baselines WHERE plan_name = :plan_name;

col description for a100
SELECT description
  FROM dba_sql_plan_baselines WHERE plan_name = :plan_name;
SET ECHO OFF;
PRO
SPO OFF;
WHENEVER SQLERROR CONTINUE;
SET DEF ON TERM ON ECHO OFF FEED 6 VER ON HEA ON LIN 80 PAGES 14 LONG 80 LONGC 80 TRIMS OFF TI OFF TIMI OFF SERVEROUT OFF NUM 10 SQLP SQL>;
SET SERVEROUT OFF;
UNDEFINE 1 2 sql_id plan_hash_value
CL COL
PRO
PRO coe_xfr_sql_baseline completed.

 

Thanks and Regards

ERP技术讨论群: 288307890
技术交流,技术讨论,欢迎加入
Technology Blog Created By Oracle ERP - 鲍新建
相关文章
|
7月前
|
存储 域名解析 弹性计算
阿里云上云流程参考:云服务器+域名+备案+域名解析绑定,全流程图文详解
对于初次通过阿里云完成上云的企业和个人用户来说,很多用户不仅是需要选购云服务器,同时还需要注册域名以及完成备案和域名的解析相关流程,从而实现网站的上线。本文将以上云操作流程为核心,结合阿里云的活动政策与用户系统梳理云服务器选购、域名注册、备案申请及域名绑定四大关键环节,以供用户完成线上业务部署做出参考。
|
负载均衡 Oracle 网络协议
Oracle中TAF与SCANIP全面解析
通过本文的解析,读者可以清晰地理解Oracle中TAF与SCAN IP的概念、工作原理及其在实际应用中的优势和局限性。TAF通过自动故障转移提升了会话的高可用性,而SCAN则通过简化客户端连接和负载均衡提升了集群的可管理性和扩展性。这两种技术在现代企业数据库架构中扮演着重要角色,能够显著提高系统的稳定性和可用性。
680 6
|
域名解析 网络协议 CDN
阿里云服务器购买后如何解析域名,三步操作即可解析绑定
阿里云服务器购买后如何解析域名,三步操作即可解析绑定
|
JavaScript 前端开发 算法
【Vue秘籍揭秘】:掌握这一个技巧,让你的列表渲染速度飙升!——深度解析`key`属性如何成为性能优化的秘密武器
【8月更文挑战第20天】Vue.js是一款流行前端框架,通过简洁API和高效虚拟DOM更新机制简化响应式Web界面开发。其中,`key`属性在列表渲染中至关重要。本文从`key`基本概念出发,解析其实现原理及最佳实践。使用`key`帮助Vue更准确地识别列表变动,优化DOM更新过程,确保组件状态正确维护,提升应用性能。通过示例展示有无`key`的区别,强调合理使用`key`的重要性。
270 3
|
缓存 前端开发 JavaScript
Webpack技术深度解析:模块打包与性能优化
【10月更文挑战第13天】Webpack技术深度解析:模块打包与性能优化
|
监控 Oracle 关系型数据库
"深度剖析:Oracle SGA大小调整策略——从组件解析到动态优化,打造高效数据库性能"
【8月更文挑战第9天】在Oracle数据库性能优化中,系统全局区(SGA)的大小调整至关重要。SGA作为一组共享内存区域,直接影响数据库处理能力和响应速度。本文通过问答形式介绍SGA调整策略:包括SGA的组成(如数据缓冲区、共享池等),如何根据负载与物理内存确定初始大小,手动调整SGA的方法(如使用`ALTER SYSTEM`命令),以及利用自动内存管理(AMM)特性实现智能调整。调整过程中需注意监控与测试,确保稳定性和性能。
1290 2
|
图形学 iOS开发 Android开发
从Unity开发到移动平台制胜攻略:全面解析iOS与Android应用发布流程,助你轻松掌握跨平台发布技巧,打造爆款手游不是梦——性能优化、广告集成与内购设置全包含
【8月更文挑战第31天】本书详细介绍了如何在Unity中设置项目以适应移动设备,涵盖性能优化、集成广告及内购功能等关键步骤。通过具体示例和代码片段,指导读者完成iOS和Android应用的打包与发布,确保应用顺利上线并获得成功。无论是性能调整还是平台特定的操作,本书均提供了全面的解决方案。
817 0
|
开发者 测试技术 Android开发
Xamarin 开发者的五大常见问题及解决方案:从环境搭建到性能优化,全面解析高效跨平台应用开发的技巧与代码实例
【8月更文挑战第31天】Xamarin 开发者常遇问题及解决方案覆盖环境搭建至应用发布全流程,助新手克服技术难关。首先需正确安装配置 Visual Studio 及 Xamarin 支持,设置 iOS/Android 测试环境。利用 Xamarin.Forms 和 XAML 实现高效跨平台开发,共享 UI 和业务逻辑代码。针对性能优化,采取减少 UI 更新、缓存计算结果等措施,复杂问题则借助 Xamarin Profiler 分析。
248 0
|
SQL 存储 数据库

热门文章

最新文章

推荐镜像

更多
下一篇
开通oss服务