主题:关于Oracle开启自动收集统计信息的SPA测试

环境:Oracle RAC 11.2.0.4(Primary + Standby)

需求:生产Primary库由于历史原因关闭了自动统计信息的收集,目前客户需求是想要重新开启统计信息的自动收集,虽然一般来说,有了更准确的统计信息,SQL会有更好的执行计划,但由于生产环境数据复杂,实际上还是需要评估哪些SQL会因为重新开启自动统计信息收集性能反而会下降。

方案:本着尽可能减少对生产Primary环境影响的原则,在Standby DG环境临时开启snapshot standby来进行SPA(SQL Performance Analyze)测试,比对开启统计信息自动收集前后的性能差异,给客户提供有价值的参考。

1.构造测试环境

**检查自动统计信息的开启状态:**
select client_name,status from dba_autotask_client;
确认自动统计信息的收集是关闭的,对于“auto optimizer stats collection”的状态应该是“DISABLED”。

SQL> select client_name,status from dba_autotask_client;

CLIENT_NAME                                                      STATUS
---------------------------------------------------------------- --------
auto optimizer stats collection DISABLED
auto space advisor ENABLED
sql tuning advisor ENABLED

附:关闭数据库的自动统计信息收集:

--光闭自动统计信息收集,(慎用,除非有其他手工收集统计信息的完整方案,否则不建议关闭)
BEGIN
DBMS_AUTO_TASK_ADMIN.disable(
client_name => 'auto optimizer stats collection',
operation => NULL,
window_name => NULL);
END;
/

DG备库保持和主库同步,所以这些设置项也都是完全一样的。

2.DG备库开启snapshot模式

主要就是在mount模式下切换数据到snapshot Standby模式再read write打开库,为之后测试做准备。下面是核心步骤:

SQL> shutdown immediate
SQL> startup mount
SQL> alter database convert to snapshot standby;
SQL> shutdown immediate
SQL> startup

关于其他细节可参考下面文章,主要是为“开启11gR2 DG的快照模式”,“后续还原成备库” 等操作提供参考:

3.SPA测试准备

进行SPA测试时,强烈建议在数据库中创建SPA测试专用用户,这样可以与其他用户区分开以及避免误操作。

SQL>
CREATE USER SPA IDENTIFIED BY SPA DEFAULT TABLESPACE SYSAUX;
GRANT DBA TO SPA;
GRANT ADVISOR TO SPA;
GRANT SELECT ANY DICTIONARY TO SPA;
GRANT ADMINISTER SQL TUNING SET TO SPA;

4.从AWR中采集SQL

备库从AWR中采集到SQL。
**4.1 获取AWR快照的边界ID**

SET LINES 188 PAGES 1000
COL SNAP_TIME FOR A22
COL MIN_ID NEW_VALUE MINID
COL MAX_ID NEW_VALUE MAXID
SELECT MIN(SNAP_ID) MIN_ID, MAX(SNAP_ID) MAX_ID
FROM DBA_HIST_SNAPSHOT
WHERE END_INTERVAL_TIME > trunc(sysdate)-10
ORDER BY 1;

我这里的结果是:

    MIN_ID     MAX_ID
---------- ----------
2755 2848

4.2 新建SQL Set

注意:以下的规范部分都是引用之前同事编写的SPA操作规范。

参考规范:

EXEC DBMS_SQLTUNE.DROP_SQLSET ( -
SQLSET_NAME => '${DBNAME}_SQLSET_${YYYYMMDD}',
SQLSET_OWNER => 'SPA'); EXEC DBMS_SQLTUNE.CREATE_SQLSET ( -
SQLSET_NAME => '${DBNAME}_SQLSET_${YYYYMMDD}', -
DESCRIPTION => 'SQL Set Create at : '||TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS'), -
SQLSET_OWNER => 'SPA');

依据我的实验环境,真实的示例为:

--连接用户
conn SPA/SPA --如果之前有这个SQLSET的名字,可以这样删除
EXEC DBMS_SQLTUNE.DROP_SQLSET (SQLSET_NAME => 'JYZHAO_SQLSET_20180106', SQLSET_OWNER => 'SPA'); --新建SQLSET:JYZHAO_SQLSET_20180106
EXEC DBMS_SQLTUNE.CREATE_SQLSET ( -
SQLSET_NAME => 'JYZHAO_SQLSET_20180106', -
DESCRIPTION => 'SQL Set Create at : '||TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS'), -
SQLSET_OWNER => 'SPA');

4.3 转化AWR数据中的SQL,将其载入到SQL Set

从备库的AWR中提取SQL(这等同于主库历史的SQL)。

参考规范:

DECLARE
SQLSET_CUR DBMS_SQLTUNE.SQLSET_CURSOR;
BEGIN
OPEN SQLSET_CUR FOR
SELECT VALUE(P) FROM TABLE(
DBMS_SQLTUNE.SELECT_WORKLOAD_REPOSITORY( &MINID, &MAXID,
'PARSING_SCHEMA_NAME NOT IN (''SYS'', ''SYSTEM'')',
NULL, NULL, NULL, NULL, 1, NULL, 'ALL')) P;
DBMS_SQLTUNE.LOAD_SQLSET(
SQLSET_NAME => '${DBNAME}_SQLSET_${YYYYMMDD}',
SQLSET_OWNER => 'SPA',
POPULATE_CURSOR => SQLSET_CUR,
LOAD_OPTION => 'MERGE',
UPDATE_OPTION => 'ACCUMULATE');
CLOSE SQLSET_CUR;
END;
/

依据我的实验环境,真实的示例为:

DECLARE
SQLSET_CUR DBMS_SQLTUNE.SQLSET_CURSOR;
BEGIN
OPEN SQLSET_CUR FOR
SELECT VALUE(P) FROM TABLE(
DBMS_SQLTUNE.SELECT_WORKLOAD_REPOSITORY( 2755, 2848,
'PARSING_SCHEMA_NAME NOT IN (''SYS'', ''SYSTEM'')',
NULL, NULL, NULL, NULL, 1, NULL, 'ALL')) P;
DBMS_SQLTUNE.LOAD_SQLSET(
SQLSET_NAME => 'JYZHAO_SQLSET_20180106',
SQLSET_OWNER => 'SPA',
POPULATE_CURSOR => SQLSET_CUR,
LOAD_OPTION => 'MERGE',
UPDATE_OPTION => 'ACCUMULATE');
CLOSE SQLSET_CUR;
END;
/

**4.4 打包SQL Set(可不做) **

参考规范:

DROP TABLE SPA.${DBNAME}_SQLSETTAB_${YYYYMMDD};
EXEC DBMS_SQLTUNE.CREATE_STGTAB_SQLSET ('${DBNAME}_SQLSETTAB_${YYYYMMDD}', ‘SPA’, 'SYSAUX');
EXEC DBMS_SQLTUNE.PACK_STGTAB_SQLSET ( -
SQLSET_NAME => '${DBNAME}_SQLSET_${YYYYMMDD}', -
SQLSET_OWNER => ‘SPA’, -
STAGING_TABLE_NAME => '${DBNAME}_SQLSETTAB_${YYYYMMDD}', -
STAGING_SCHEMA_OWNER => ‘SPA’);

依据我的实验环境,真实的示例为:

DROP TABLE SPA.JYZHAO_SQLSETTAB_20180106;
EXEC DBMS_SQLTUNE.CREATE_STGTAB_SQLSET ('JYZHAO_SQLSETTAB_20180106', 'SPA', 'SYSAUX');
EXEC DBMS_SQLTUNE.PACK_STGTAB_SQLSET ( -
SQLSET_NAME => 'JYZHAO_SQLSET_20180106', -
SQLSET_OWNER => 'SPA', -
STAGING_TABLE_NAME => 'JYZHAO_SQLSETTAB_20180106', -
STAGING_SCHEMA_OWNER => 'SPA');

说明:其实在我这里的测试场景下,这一步是不需要做的。因为备库的SQL Set可以直接在后面引用,不需要像SPA经典场景中,是从生产源环境打包导出来后,在测试环境再导入进去,再解包为SQL Set。

5.SPA分析比较

**5.1 创建SPA分析任务**
参考规范:

VARIABLE SPA_TASK  VARCHAR2(64);
EXEC :SPA_TASK := DBMS_SQLPA.CREATE_ANALYSIS_TASK( -
TASK_NAME => 'SPA_TASK_${YYYYMMDD}', -
DESCRIPTION => 'SPA Analysis task at : '||TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS'), -
SQLSET_NAME => '${DBNAME}_SQLSET_${YYYYMMDD}', -
SQLSET_OWNER => ‘SPA’);

依据我的实验环境,真实的示例为:

--创建SPA分析任务:
VARIABLE SPA_TASK VARCHAR2(64);
EXEC :SPA_TASK := DBMS_SQLPA.CREATE_ANALYSIS_TASK( -
TASK_NAME => 'SPA_TASK_20180106', -
DESCRIPTION => 'SPA Analysis task at : '||TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS'), -
SQLSET_NAME => 'JYZHAO_SQLSET_20180106', -
SQLSET_OWNER => 'SPA');

5.2 获取变更前的SQL执行效率

参考规范:

EXEC DBMS_SQLPA.EXECUTE_ANALYSIS_TASK( -
TASK_NAME => 'SPA_TASK_${YYYYMMDD}', -
EXECUTION_NAME => 'EXEC_10G_${YYYYMMDD}', -
EXECUTION_TYPE => 'CONVERT SQLSET', -
EXECUTION_DESC => 'Convert 10g SQLSET for SPA Task at : '||TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS'));

依据我的实验环境,真实的示例为:

EXEC DBMS_SQLPA.EXECUTE_ANALYSIS_TASK( -
TASK_NAME => 'SPA_TASK_20180106', -
EXECUTION_NAME => 'EXEC_BEFORE_20180106', -
EXECUTION_TYPE => 'CONVERT SQLSET', -
EXECUTION_DESC => 'Convert Before gathering stats SQLSET for SPA Task at : '||TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS'));

5.3 开启变更操作

变更内容:开启统计信息自动收集并确认已经成功收集了最新的统计信息。

这里首先需要开启统计信息自动收集,并可以把自动收集的窗口时间提前到现在,减少等待的时间。

--检查自动统计信息的开启状态:
select client_name,status from dba_autotask_client; --启动自动统计信息收集
BEGIN
DBMS_AUTO_TASK_ADMIN.enable(
client_name => 'auto optimizer stats collection',
operation => NULL,
window_name => NULL);
END;
/

查看窗口任务和有关统计信息自动收集的任务执行状态:

select window_name,repeat_interval,duration,enabled from dba_scheduler_windows;
select owner, job_name, status, ACTUAL_START_DATE, RUN_DURATION from dba_scheduler_job_run_details where job_name like 'ORA$AT_OS_OPT_S%' order by 4;

调整窗口任务的下一次执行时间:

--需要确认JOB可以启动
alter system set job_queue_processes=1000; --调整窗口任务的下一次执行时间
EXEC DBMS_SCHEDULER.SET_ATTRIBUTE('SATURDAY_WINDOW','repeat_interval','freq=daily;byday=SAT;byhour=17;byminute=10;bysecond=0');

更多有关调整窗口和自动任务的内容可参考文章:

5.4 变更后再次分析性能

测试运行SQL Tuning Set中的SQL语句,分析所有语句在收集统计信息之后的执行效率:

参考规范:

EXEC DBMS_SQLPA.EXECUTE_ANALYSIS_TASK( -
TASK_NAME => 'SPA_TASK_${YYYYMMDD}', -
EXECUTION_NAME => 'EXEC_11G_${YYYYMMDD}', -
EXECUTION_TYPE => 'TEST EXECUTE', -
EXECUTION_DESC => 'Execute SQL in 11g for SPA Task at : '||TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS'));

依据我的实验环境,真实的示例为:

EXEC DBMS_SQLPA.EXECUTE_ANALYSIS_TASK( -
TASK_NAME => 'SPA_TASK_20180106', -
EXECUTION_NAME => 'EXEC_AFTER_20180106', -
EXECUTION_TYPE => 'TEST EXECUTE', -
EXECUTION_DESC => 'Execute SQL After gathering stats for SPA Task at : '||TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS'));

5.5 变更前后性能对比

得到两次SQL Trail之后,可以对比两次Trial之间的SQL执行性能,可以从不同的维度对两次Trail中的所有SQL进行对比分析,主要关注的维度有:SQL执行时间,SQL执行的CPU时间,SQL执行的逻辑读。

参考规范:

1). 对比两次Trail中的SQL执行时间
EXEC DBMS_SQLPA.EXECUTE_ANALYSIS_TASK( -
TASK_NAME => 'SPA_TASK_${YYYYMMDD}', -
EXECUTION_NAME => 'COMPARE_ET_${YYYYMMDD}', -
EXECUTION_TYPE => 'COMPARE PERFORMANCE', -
EXECUTION_PARAMS => DBMS_ADVISOR.ARGLIST( -
'COMPARISON_METRIC', 'ELAPSED_TIME', -
'EXECUTE_FULLDML', 'TRUE', -
'EXECUTION_NAME1','EXEC_10G_${YYYYMMDD}', -
'EXECUTION_NAME2','EXEC_11G_${YYYYMMDD}'), -
EXECUTION_DESC => 'Compare SQLs between 10g and 11g at :'||TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS'));
2). 对比两次Trail中的SQL执行的CPU时间
EXEC DBMS_SQLPA.EXECUTE_ANALYSIS_TASK( -
TASK_NAME => 'SPA_TASK_${YYYYMMDD}', -
EXECUTION_NAME => 'COMPARE_CT_${YYYYMMDD}', -
EXECUTION_TYPE => 'COMPARE PERFORMANCE', -
EXECUTION_PARAMS => DBMS_ADVISOR.ARGLIST( -
'COMPARISON_METRIC', 'CPU_TIME', -
'EXECUTION_NAME1','EXEC_10G_${YYYYMMDD}', -
'EXECUTION_NAME2','EXEC_11G_${YYYYMMDD}'), -
EXECUTION_DESC => 'Compare SQLs between 10g and 11g at :'||TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS'));
3). 对比两次Trail中的SQL执行的逻辑读
EXEC DBMS_SQLPA.EXECUTE_ANALYSIS_TASK( -
TASK_NAME => 'SPA_TASK_D', -
EXECUTION_NAME => 'COMPARE_BG_D', -
EXECUTION_TYPE => 'COMPARE PERFORMANCE', -
EXECUTION_PARAMS => DBMS_ADVISOR.ARGLIST( -
'COMPARISON_METRIC', 'BUFFER_GETS', -
'EXECUTION_NAME1','EXEC_10G_${YYYYMMDD}', -
'EXECUTION_NAME2','EXEC_11G_${YYYYMMDD}'), -
EXECUTION_DESC => 'Compare SQLs between 10g and 11g at :'||TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS'));

依据我的实验环境,真实的示例为:

1). 对比两次Trail中的SQL执行时间
EXEC DBMS_SQLPA.EXECUTE_ANALYSIS_TASK( -
TASK_NAME => 'SPA_TASK_20180106', -
EXECUTION_NAME => 'COMPARE_ET_20180106', -
EXECUTION_TYPE => 'COMPARE PERFORMANCE', -
EXECUTION_PARAMS => DBMS_ADVISOR.ARGLIST( -
'COMPARISON_METRIC', 'ELAPSED_TIME', -
'EXECUTE_FULLDML', 'TRUE', -
'EXECUTION_NAME1','EXEC_BEFORE_20180106', -
'EXECUTION_NAME2','EXEC_AFTER_20180106'), -
EXECUTION_DESC => 'Compare SQLs between 10g and 11g at :'||TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS'));
2). 对比两次Trail中的SQL执行的CPU时间
EXEC DBMS_SQLPA.EXECUTE_ANALYSIS_TASK( -
TASK_NAME => 'SPA_TASK_20180106', -
EXECUTION_NAME => 'COMPARE_CT_20180106}', -
EXECUTION_TYPE => 'COMPARE PERFORMANCE', -
EXECUTION_PARAMS => DBMS_ADVISOR.ARGLIST( -
'COMPARISON_METRIC', 'CPU_TIME', -
'EXECUTION_NAME1','EXEC_BEFORE_20180106', -
'EXECUTION_NAME2','EXEC_AFTER_20180106'), -
EXECUTION_DESC => 'Compare SQLs between 10g and 11g at :'||TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS'));
3). 对比两次Trail中的SQL执行的逻辑读
EXEC DBMS_SQLPA.EXECUTE_ANALYSIS_TASK( -
TASK_NAME => 'SPA_TASK_20180106', -
EXECUTION_NAME => 'COMPARE_BG_20180106', -
EXECUTION_TYPE => 'COMPARE PERFORMANCE', -
EXECUTION_PARAMS => DBMS_ADVISOR.ARGLIST( -
'COMPARISON_METRIC', 'BUFFER_GETS', -
'EXECUTION_NAME1','EXEC_BEFORE_20180106', -
'EXECUTION_NAME2','EXEC_AFTER_20180106'), -
EXECUTION_DESC => 'Compare SQLs between Before_STATS and After_STATS at :'||TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS'));

6.获取性能比对分析报告

参考规范:

--a)  获取执行时间全部报告
ALTER SESSION SET EVENTS='31156 TRACE NAME CONTEXT FOREVER, LEVEL 0X400';
SET LINES 1111 PAGES 50000 LONG 1999999999 TRIM ON TRIMS ON SERVEROUTPUT ON SIZE UNLIMITED
SPOOL elapsed_all.html
SELECT XMLTYPE(DBMS_SQLPA.REPORT_ANALYSIS_TASK('SPA_TASK_${YYYYMMDD}','HTML','ALL','ALL',NULL,1000,'SPA_TASK_${YYYYMMDD}_COMP_ET')).GETCLOBVAL(0,0) FROM DUAL;
--b) 获取执行时间下降报告
ALTER SESSION SET EVENTS='31156 TRACE NAME CONTEXT FOREVER, LEVEL 0X400';
SET LINES 1111 PAGES 50000 LONG 1999999999 TRIM ON TRIMS ON SERVEROUTPUT ON SIZE UNLIMITED
SPOOL elapsed_regressed.html
SELECT XMLTYPE(DBMS_SQLPA.REPORT_ANALYSIS_TASK('SPA_TASK_${YYYYMMDD}','HTML','REGRESSED','ALL',NULL,1000,'SPA_TASK_${YYYYMMDD}_COMP_ET')).GETCLOBVAL(0,0) FROM DUAL;
--c) 获取逻辑读全部报告
ALTER SESSION SET EVENTS='31156 TRACE NAME CONTEXT FOREVER, LEVEL 0X400';
SET LINES 1111 PAGES 50000 LONG 1999999999 TRIM ON TRIMS ON SERVEROUTPUT ON SIZE UNLIMITED
SPOOL buffer_all.html
SELECT XMLTYPE(DBMS_SQLPA.REPORT_ANALYSIS_TASK('SPA_TASK_${YYYYMMDD}','HTML','ALL','ALL',NULL,1000,'SPA_TASK_${YYYYMMDD}_COMP_BG')).GETCLOBVAL(0,0) FROM DUAL;
--d) 获取逻辑读下降报告
ALTER SESSION SET EVENTS='31156 TRACE NAME CONTEXT FOREVER, LEVEL 0X400';
SET LINES 1111 PAGES 50000 LONG 1999999999 TRIM ON TRIMS ON SERVEROUTPUT ON SIZE UNLIMITED
SPOOL buffer_regressed.html
SELECT XMLTYPE(DBMS_SQLPA.REPORT_ANALYSIS_TASK('SPA_TASK_${YYYYMMDD}','HTML','REGRESSED','ALL',NULL,1000,'SPA_TASK_${YYYYMMDD}_COMP_BG')).GETCLOBVAL(0,0) FROM DUAL;
--e) 获取错误报告
ALTER SESSION SET EVENTS='31156 TRACE NAME CONTEXT FOREVER, LEVEL 0X400';
SET LINES 1111 PAGES 50000 LONG 1999999999 TRIM ON TRIMS ON SERVEROUTPUT ON SIZE UNLIMITED
SPOOL error.html
SELECT XMLTYPE(DBMS_SQLPA.REPORT_ANALYSIS_TASK('SPA_TASK_${YYYYMMDD}','HTML','ERRORS','ALL',NULL,1000,'SPA_TASK_${YYYYMMDD}_COMP_ET')).GETCLOBVAL(0,0) FROM DUAL;
--f) 获取不支持报告
ALTER SESSION SET EVENTS='31156 TRACE NAME CONTEXT FOREVER, LEVEL 0X400';
SET LINES 1111 PAGES 50000 LONG 1999999999 TRIM ON TRIMS ON SERVEROUTPUT ON SIZE UNLIMITED
SPOOL unsupported.html
SELECT XMLTYPE(DBMS_SQLPA.REPORT_ANALYSIS_TASK('SPA_TASK_${YYYYMMDD}','HTML','UNSUPPORTED','ALL',NULL,1000,'SPA_TASK_${YYYYMMDD}_COMP_ET')).GETCLOBVAL(0,0) FROM DUAL;
--g) 获取执行计划变化报告
ALTER SESSION SET EVENTS='31156 TRACE NAME CONTEXT FOREVER, LEVEL 0X400';
SET LINES 1111 PAGES 50000 LONG 1999999999 TRIM ON TRIMS ON SERVEROUTPUT ON SIZE UNLIMITED
SPOOL changed_plans.html
SELECT XMLTYPE(DBMS_SQLPA.REPORT_ANALYSIS_TASK('SPA_TASK_${YYYYMMDD}','HTML','CHANGED_PLANS','ALL',NULL,1000,'SPA_TASK_${YYYYMMDD}_COMP_ET')).GETCLOBVAL(0,0) FROM DUAL;

依据我的实验环境,真实的示例为:

--a)  获取执行时间全部报告
ALTER SESSION SET EVENTS='31156 TRACE NAME CONTEXT FOREVER, LEVEL 0X400';
SET LINES 1111 PAGES 50000 LONG 1999999999 TRIM ON TRIMS ON SERVEROUTPUT ON SIZE UNLIMITED
SPOOL elapsed_all.html
SELECT XMLTYPE(DBMS_SQLPA.REPORT_ANALYSIS_TASK('SPA_TASK_20180106','HTML','ALL','ALL',NULL,1000,'COMPARE_ET_20180106')).GETCLOBVAL(0,0) FROM DUAL;
--b) 获取执行时间下降报告
ALTER SESSION SET EVENTS='31156 TRACE NAME CONTEXT FOREVER, LEVEL 0X400';
SET LINES 1111 PAGES 50000 LONG 1999999999 TRIM ON TRIMS ON SERVEROUTPUT ON SIZE UNLIMITED
SPOOL elapsed_regressed.html
SELECT XMLTYPE(DBMS_SQLPA.REPORT_ANALYSIS_TASK('SPA_TASK_20180106','HTML','REGRESSED','ALL',NULL,1000,'COMPARE_ET_20180106')).GETCLOBVAL(0,0) FROM DUAL;
--c) 获取逻辑读全部报告
ALTER SESSION SET EVENTS='31156 TRACE NAME CONTEXT FOREVER, LEVEL 0X400';
SET LINES 1111 PAGES 50000 LONG 1999999999 TRIM ON TRIMS ON SERVEROUTPUT ON SIZE UNLIMITED
SPOOL buffer_all.html
SELECT XMLTYPE(DBMS_SQLPA.REPORT_ANALYSIS_TASK('SPA_TASK_20180106','HTML','ALL','ALL',NULL,1000,'COMPARE_BG_20180106')).GETCLOBVAL(0,0) FROM DUAL;
--d) 获取逻辑读下降报告
ALTER SESSION SET EVENTS='31156 TRACE NAME CONTEXT FOREVER, LEVEL 0X400';
SET LINES 1111 PAGES 50000 LONG 1999999999 TRIM ON TRIMS ON SERVEROUTPUT ON SIZE UNLIMITED
SPOOL buffer_regressed.html
SELECT XMLTYPE(DBMS_SQLPA.REPORT_ANALYSIS_TASK('SPA_TASK_20180106','HTML','REGRESSED','ALL',NULL,1000,'COMPARE_BG_20180106')).GETCLOBVAL(0,0) FROM DUAL;
--e) 获取错误报告
ALTER SESSION SET EVENTS='31156 TRACE NAME CONTEXT FOREVER, LEVEL 0X400';
SET LINES 1111 PAGES 50000 LONG 1999999999 TRIM ON TRIMS ON SERVEROUTPUT ON SIZE UNLIMITED
SPOOL error.html
SELECT XMLTYPE(DBMS_SQLPA.REPORT_ANALYSIS_TASK('SPA_TASK_20180106','HTML','ERRORS','ALL',NULL,1000,'COMPARE_ET_20180106')).GETCLOBVAL(0,0) FROM DUAL;
--f) 获取不支持报告
ALTER SESSION SET EVENTS='31156 TRACE NAME CONTEXT FOREVER, LEVEL 0X400';
SET LINES 1111 PAGES 50000 LONG 1999999999 TRIM ON TRIMS ON SERVEROUTPUT ON SIZE UNLIMITED
SPOOL unsupported.html
SELECT XMLTYPE(DBMS_SQLPA.REPORT_ANALYSIS_TASK('SPA_TASK_20180106','HTML','UNSUPPORTED','ALL',NULL,1000,'COMPARE_ET_20180106')).GETCLOBVAL(0,0) FROM DUAL;
--g) 获取执行计划变化报告
ALTER SESSION SET EVENTS='31156 TRACE NAME CONTEXT FOREVER, LEVEL 0X400';
SET LINES 1111 PAGES 50000 LONG 1999999999 TRIM ON TRIMS ON SERVEROUTPUT ON SIZE UNLIMITED
SPOOL changed_plans.html
SELECT XMLTYPE(DBMS_SQLPA.REPORT_ANALYSIS_TASK('SPA_TASK_20180106','HTML','CHANGED_PLANS','ALL',NULL,1000,'COMPARE_ET_20180106')).GETCLOBVAL(0,0) FROM DUAL;

这样就得到了各类的性能对比报告,以执行时间的全部报告为例,生成的报告概要头部类似这样:



当然,具体获取到的这些性能对比报告,针对那些有性能下降的SQL,还需要人工干预,评估如何优化处理那些性能下降的SQL。

关于Oracle开启自动收集统计信息的SPA测试的更多相关文章

  1. Oracle之自动收集统计信息

    一.Oracle 11g 在Oracle的11g版本中提供了统计数据自动收集的功能.在部署安装11g Oracle软件过程中,其中有一个步骤便是提示是否启动这个功能(默认是启用这个功能). 在这里介绍 ...

  2. oracle会自动收集统计信息-记住哦

    oracle自动收集统计信息,周一至周五  时间:22:00:00 oracle自动收集统计信息,周六.周日  时间:06:00:00

  3. [转帖] Oracle 关闭自动收集统计信息

    --关闭自动统计信息 https://blog.csdn.net/royzhang7/article/details/51172556 明天再仔细看一下. select client_name,sta ...

  4. Oracle 10g 之自动收集统计信息

    从10g开始,Oracle在建库后就默认创建了一个名为GATHER_STATS_JOB的定时任务,用于自动收集CBO的统计信息.这个自动任务默认情况下在工作日晚上10:00-6:00和周末全天开启. ...

  5. Oracle 11g 之自动收集统计信息

    在Oracle的11g版本中提供了统计数据自动收集的功能.在部署安装11g Oracle软件过程中,其中有一个步骤便是提示是否启动这个功能(默认是启用这个功能). 1.查看自动收集统计信息的任务及状态 ...

  6. Oracle中的统计信息

    一.什么是统计信息 统计信息主要是描述数据库中表,索引的大小,规模,数据分布状况等的一类信息.例如,表的行数,块数,平均每行的大小,索引的leaf blocks,索引字段的行数,不同值的大小等,都属于 ...

  7. ORA-03001,GATHER_TABLE_STATS数据库自动收集统计信息报错

    1.根据Alert报错信息,查询Trace日志 /oracle/app/oracle/admin/fgsquery/bdump/fgsquery_j001_11111.trc Oracle Datab ...

  8. 基于Oracle的SQL优化(崔华著)-整理笔记-第5章“Oracle里的统计信息”

    第5章“Oracle里的统计信息” 详细介绍了Oracle数据库里与统计信息相关的各个方面的内容,包括 Oracle数据库中各种统计信息的分类.含义.收集和查看方法,以及如何在Oracle数据库里正确 ...

  9. oracle里的统计信息

    1 oracle里的统计信息 Oracle的统计信息是这样的一组数据,存储在数据字典,从多个维度描述了oracle数据库对象的详细信息,有6种类型 表的统计信息:记录数.表块的数量.平均行长度等 索引 ...

随机推荐

  1. WireShark 使用

    1.干货 Wireshark(前称Ethereal)是一个网络封包分析软件.网络封包分析软件的功能是撷取网络封包,并尽可能显示出最为详细的网络封包资料.Wireshark使用WinPCAP作为接口,直 ...

  2. 深入解析Java垃圾回收机制

    引入垃圾回收 哪些内存需要回收? 引用计数法 可达性分析 如何回收 Marking 标记 Normal Deletion 清除 Deletion with Compacting 压缩 为什么需要分代收 ...

  3. 使用vee-validate表单插件是如何设置中文提示?

    最近在写vue表单验证的时候,在网上找到一款不错的插件vee-validate,在使用的过程中发现配置不了中文提示,这就很苦恼了,基本上网上的配置办法我都看过,都是有问题的,比如这种 import z ...

  4. 关于APIcloud中的登录与注册的简单实现

    1.apiclou实现页面的登录方式,不适用自带的登录. html代码 <div class="login_ipt_box"> <img class=" ...

  5. System.ServiceModel.CommunicationException: 已超过传入消息(65536)的最大消息大小配额。若要增加配额,请使用相应绑定元素上的 MaxReceivedMessageSize 属性。

  6. PKI(公钥基础设施)基础知识笔记

    数字签名 数字签名(又称公钥数字签名.电子签章)是一种类似写在纸上的普通的物理签名,可是使用了公钥加密领域的技术实现.用于鉴别数字信息的方法. 一套数字签名通常定义两种互补的运算.一个用于签名,还有一 ...

  7. path和classpath细节

    从学习java的最初我们就被要求先设置path变量和classpath变量.但是这两个环境变量到底有什么作用呢? 1.path环境变量 path环境变量的主要作用是告诉操作系统到哪里去寻找某个程序,如 ...

  8. java与数据库

    工具:mysql: java eclipse,phpstudy. 以MySQL为例 java连接MySQL可能你在度娘的帮助下,又设置环境变量又改这改那的,结果还是没有连接成功. 今天我来分享一下不需 ...

  9. [.Net跨平台]部署DTCMS到Jexus遇到的问题及解决思路---Linux环境搭建

    最近朋友托我帮忙研究如何把一个DTCMS部署到Linux下,经过1天的研究,部署基本成功,可能有些细节还未注意到,现在把心得分享一下.过程比预期的要简单 身为.Net程序员,这个问题的第一步可能就是如 ...

  10. ligerUI---ligerForm中下拉框使用

    写在前面: 最近项目的前框框架用的是ligerUI,一开始我是拒绝的,因为貌似ligerUI很少有人用,我真的很想问我们team的斌哥哥为什么要用ligerUI来做前端框架?????(啊哈哈哈,用什么 ...