主題:關於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。