SQL Performance Analyzer SPA常用腳本彙總
SQL 性能分析器 SQL Performance Analyzer SPA
Oracle Database 11g 引入了 SQL 性能分析器;使用該工具可以準確地評估更改對組成工作量的 SQL 語句的影響。SQL 性能分析器可幫助預測潛在的更改對 SQL 查詢工作量的性能影響。這種功能可向 DBA 提供有關 SQL 語句性能的詳細信息,例如,執行前後的統計信息,提高或降低性能的語句。這樣一來,您就可以執行諸如以下操作的操作:在測試環境中進行更改,以確定數據庫升級是否會改進工作量性能。
- 11g 的新增功能
- 目標用戶:DBA、QA、應用程序開發人員
- 幫助預測系統更改對 SQL 工作量響應時間的影響
- 建立不同版本的 SQL 工作量性能(即 SQL 執行計劃和執行統計信息)
- 以串行方式執行 SQL(不考慮併發性)
- 分析性能差異
- 提供對單個 SQL 的細粒度性能分析
- 與 SQL 優化指導集成在一起以優化迴歸
SQL 性能分析器:使用情形
SQL 性能分析器可用於預測和防止會影響 SQL 執行計劃結構的任何數據庫環境更改所帶來的潛在性能問題。這些更改可以包括(但不限於)以下任何一種更改:
- 數據庫升級
- 實施優化建議
- 更改方案
- 收集統計信息
- 更改數據庫參數
- 更改操作系統和硬件
DBA 甚至可以使用 SQL 性能分析器爲最複雜的環境預測先期更改導致的 SQL 性能更改。例如,隨着應用程序在開發週期中的變化,數據庫應用程序開發人員可以測試對方案、 數據庫對象和重寫應用程序的更改,以減輕任何潛在的性能影響。
使用 SQL 性能分析器還可以比較 SQL 性能統計信息。
SQL 性能分析器:概要
1. 收集 SQL:在這個階段中,將收集用於表示生產系統中的 SQL 工作量的 SQL 語句集。可以使用 SQL 優化集或自動工作量資料檔案庫 (AWR) 來捕獲要傳送的信息。因爲 AWR 本質上是捕獲高負載的 SQL,所以應考慮修改默認的 AWR 快照設置和捕獲的頂級 SQL,以確保 AWR 捕獲最大數量的 SQL 語句。這可以確保捕獲更加完整的 SQL 工作量。
2. 傳送:在這個階段中,應將得到的工作量結果傳送到測試系統。從生產系統導出 STS,然後將 STS 導入到測試系統。
3. 計算“之前版本”性能:在進行任何更改之前,執行 SQL 語句,收集評估將來的更改對工作量性能的可能影響所需的基線信息。在此階段收集的信息給出了系統工作量當前狀態的一個快照。性能數據包括:
4. 進行更改:獲得了之前版本數據後,可以實施計劃的更改,然後開始查看對性能的影響。
5. 計算“之後版本”性能:在數據庫環境中進行了更改之後才執行此步驟。SQL 工作量的每個語句都在虛擬執行(僅收集統計信息)模式下運行,收集與步驟 3 所捕獲的信息相同的信息。
6. 比較和分析 SQL 性能:在獲得了兩個版本的 SQL 工作量性能數據後,可以通過比較之後版本與之前版本的數據來進行性能分析。比較的根據是執行統計信息,如所用時間、CPU 時間和緩衝區獲取次數等。
7. 優化迴歸的 SQL:在此階段中,已經準確地確認了哪些 SQL 語句在進行數據庫更改時可能導致性能問題。在此階段中可以使用任何一種數據庫工具來優化系統。例如,可以對確認的語句使用 SQL 優化指導或訪問指導,然後實施相應的建議。也可以使用在步驟 3 中捕獲的計劃植入 SQL 計劃管理 (SPM) 以確保計劃保持不變。在實施了任何優化操作後,應重複該過程來創建新的之後版本,然後分析性能差異以確保新的性能是可接受的。
默認情況下SPA若涉及到DML語句則只有查詢部分Query會被執行,但是貌似是從11.2開始可以執行完全的DML了,需要加入參數EXECUTE_FULLDML,但是該參數目前有一些BUG:
Bug 10428438 : WITH EXECUTE_FULLDML ROWS IS ALWAYS SET TO 0 11.2.0.1
Bug 14635522 : SPA SHOULD CAPTURE AND REPLAY TRANSACTIONS 11.2.0.3
By default, only the query portion of DMLs is executed. Using APIs, you can execute the full DML by using the EXECUTE_FULLDML task parameter.EXECUTE_FULLDML when set to TRUE executes DML statement fully, including acquiring row locks and modifying rows; When EXECUTE_FULLDML is set to FALSE (the default value is false) to execute only the query part of the DML without modifying data. When TRUE, SQL Performance Analyzer will issue a rollback following DML execution to prevent persistent changes from being made by the DML. So SPA does not make make any change to the data in the tables.
執行方法如下:
execute DBMS_SQLPA.SET_ANALYSIS_TASK_PARAMETER(task_name => 'TASK_21137', - parameter => 'EXECUTE_FULLDML', - value => 'TRUE');
從cursor cache中收集tuning set, 持續12分鐘,間隔5秒鐘
begin DBMS_SQLTUNE.CREATE_SQLSET (sqlset_name => 'MAC_SPA'); dbms_sqltune.capture_cursor_cache_sqlset( sqlset_name => 'MAC_SPA' , time_limit => 12*60, repeat_interval => 5); end ; / basic_filter=> q'# module like 'DWH_TEST%' and sql_text not like '%applicat%' and parsing_schema_name in ('APPS') #' basic_filter => 'sql_text LIKE ''%my_objects%'' and parsing_schema_name = ''SPA_TEST_USER''', ==>過濾條件使用
從當前cursor cache中匹配條件 獲得SQLset ROW
SELECT sql_id, sql_text FROM table(DBMS_SQLTUNE.SELECT_CURSOR_CACHE('buffer_gets > 500')) ORDER BY sql_id; SELECT * FROM table(DBMS_SQLTUNE.SELECT_CURSOR_CACHE('sql_id = ''4rm4183czbs7j''')); DECLARE cur sys_refcursor; BEGIN OPEN cur FOR SELECT value(P) FROM table(DBMS_SQLTUNE.SELECT_CURSOR_CACHE) P; -- Process each statement (or pass cursor to load_sqlset). CLOSE cur; END; / -- create the tuning set EXEC DBMS_SQLTUNE.CREATE_SQLSET('MAC_SPA'); -- populate the tuning set from the cursor cache DECLARE cur DBMS_SQLTUNE.SQLSET_CURSOR; BEGIN OPEN cur FOR SELECT VALUE(P) FROM table( DBMS_SQLTUNE.SELECT_CURSOR_CACHE( 'parsing_schema_name <> ''SYS'' AND elapsed_time > 5000000', NULL, NULL, NULL, NULL, 1, NULL, 'ALL')) P; DBMS_SQLTUNE.LOAD_SQLSET(sqlset_name => 'MAC_SPA', populate_cursor => cur); END; /
從AWR快照中加載SQLset ROW到SQL TUNING SET
DECLARE cur sys_refcursor; BEGIN OPEN cur FOR SELECT VALUE (P) FROM table(dbms_sqltune.select_workload_repository(4146,4161)) P; -- Process each statement (or pass cursor to load_sqlset) DBMS_SQLTUNE.LOAD_SQLSET(sqlset_name => 'MAC_SPA', populate_cursor => cur); CLOSE cur; END; /
將SQL TUNING SET Pack到表中:
set echo on select name,statement_count from dba_sqlset; drop table maclean.pack_sqlset purge; exec DBMS_SQLTUNE.CREATE_STGTAB_SQLSET('PACK_SQLSET','MACLEAN'); exec DBMS_SQLTUNE.PACK_STGTAB_SQLSET('MAC_SPA','SYS','PACK_SQLSET','MACLEAN'); SQL> desc maclean.pack_sqlset; Name Null? Type ----------------------------------------- -------- ---------------------------- NAME VARCHAR2(30) OWNER VARCHAR2(30) DESCRIPTION VARCHAR2(256) SQL_ID VARCHAR2(13) FORCE_MATCHING_SIGNATURE NUMBER SQL_TEXT CLOB PARSING_SCHEMA_NAME VARCHAR2(30) BIND_DATA RAW(2000) BIND_LIST SQL_BIND_SET MODULE VARCHAR2(48) ACTION VARCHAR2(32) ELAPSED_TIME NUMBER CPU_TIME NUMBER BUFFER_GETS NUMBER DISK_READS NUMBER DIRECT_WRITES NUMBER ROWS_PROCESSED NUMBER FETCHES NUMBER EXECUTIONS NUMBER END_OF_FETCH_COUNT NUMBER OPTIMIZER_COST NUMBER OPTIMIZER_ENV RAW(1000) PRIORITY NUMBER COMMAND_TYPE NUMBER FIRST_LOAD_TIME VARCHAR2(19) STAT_PERIOD NUMBER ACTIVE_STAT_PERIOD NUMBER OTHER CLOB PLAN_HASH_VALUE NUMBER PLAN SQL_PLAN_TABLE_TYPE SPARE1 NUMBER SPARE2 NUMBER SPARE3 BLOB SPARE4 CLOB
將測試對應 schema的數據和 上述PACK TABLE 導出導入到 目標測試庫中:
set echo on exec DBMS_SQLTUNE.UNPACK_STGTAB_SQLSET('MAC_SPA','SYS',TRUE,'PACK_SQLSET','MACLEAN'); alter system flush buffer_cache; alter system flush shared_pool;
創建SPA任務 並運行;
var sts_task varchar2(64); exec :sts_task:= dbms_sqlpa.create_analysis_task(task_name => '10g_11g_spa',description => 'experiment for 10gR2 to 11gR2 upgrade',sqlset_name=> 'MAC_SPA'); PL/SQL procedure successfully completed. var exe_task varchar2(64); exec :exe_task:=dbms_sqlpa.execute_analysis_task(task_name=>'10g_11g_spa',execution_name=>'10g_trail',execution_type=>'CONVERT SQLSET',execution_desc=>'10g sql trail'); var exe_task varchar2(64); exec :exe_task:=dbms_sqlpa.execute_analysis_task(task_name=>'10g_11g_spa',execution_name=>'11g_trail',execution_type=>'TEST EXECUTE',execution_desc=>'11g sql trail');
執行任務比較
比較CPU_TIME EXEC dbms_sqlpa.execute_analysis_task( - task_name => '10g_11g_spa', - execution_name => 'compare_10g_112_cpu', - execution_type => 'COMPARE PERFORMANCE', - execution_params => dbms_advisor.arglist('COMPARISON_METRIC','CPU_TIME','EXECUTION_NAME1','10g_trail','EXECUTION_NAME2','11g_trail'), - execution_desc => 'Compare 10g SQL Trace Performance to 11g Test-Execute for CPU_TIME') / 比較BUFFER_GETS EXEC dbms_sqlpa.execute_analysis_task( - task_name => '10g_11g_spa', - execution_name => 'compare_10g_112_buffergets', - execution_type => 'COMPARE PERFORMANCE', - execution_params => dbms_advisor.arglist('COMPARISON_METRIC','BUFFER_GETS','EXECUTION_NAME1','10g_trail','EXECUTION_NAME2','11g_trail'), - execution_desc => 'Compare 10g SQL Trace Performance to 11g Test-Execute for BUFFER_GETS') / 比較實際執行時長 begin DBMS_SQLPA.EXECUTE_ANALYSIS_TASK( task_name => 'SPA_TEST', execution_type => 'COMPARE PERFORMANCE', execution_name => 'Compare_elapsed_time', execution_params => dbms_advisor.arglist('execution_name1', '10g_trail', 'execution_name2', '11g_trail', 'comparison_metric', 'elapsed_time') ); end; / 比較物理讀 begin DBMS_SQLPA.EXECUTE_ANALYSIS_TASK( task_name => '10g_11g_spa', execution_type => 'COMPARE PERFORMANCE', execution_name => 'Compare_physical_reads0', execution_params => dbms_advisor.arglist('execution_name1', '10g_trail', 'execution_name2', '11g_trail', 'comparison_metric', 'disk_reads') ); end; / Set the comparison_metric parameter to specify an expression of execution statistics to use in the performance impact analysis. Possible values include the following metrics or any combination of them: elapsed_time (default), cpu_time, buffer_gets, disk_reads, direct_writes, and optimizer_cost.
獲得SPA報告:
set long 100000 longchunksize 100000 linesize 200 head off feedback off echo off spool spa_report_elapsed_time.html SELECT dbms_sqlpa.report_analysis_task('SPA_TEST', 'HTML', 'ALL','ALL', execution_name=>'Compare_elapsed_time') FROM dual; spool off 產生buffergets 比較report set heading off long 100000000 longchunksize 10000 echo off; set linesize 1000 trimspool on; spool buffergets_summary.html select xmltype(dbms_sqlpa.report_analysis_task('10g_11g_spa', 'html', 'typical', 'all', null, 100, 'compare_10g_112_buffergets')).getclobval(0,0) from dual; spool off 產生errors比較report spool errors_summary.html select xmltype(dbms_sqlpa.report_analysis_task('10g_11g_spa', 'html', 'errors', 'summary', null, 100, '11g_trail')).getclobval(0,0) from dual; spool off 產生unsupport比較report spool unsuppor_all.html select xmltype(dbms_sqlpa.report_analysis_task('10g_11g_spa', 'html', 'unsupported', 'all', null, 100, '11g_trail')).getclobval(0,0) from dual; spool off
execution_type
Type of the action to perform by the function. If NULL it will default to the value of the DEFAULT_EXECUTION_TYPE parameter. Possible values are:
[TEST] EXECUTE – test-execute every SQL statement and collect its execution plans and execution statistics. The resulting plans and statistics will be stored in the advisor framework. This
is default.
EXPLAIN PLAN – generate explain plan for every statement in the SQL workload. This is similar to the EXPLAIN PLAN command. The resulting plans will be stored in the advisor framework in
association with the task.
COMPARE [PERFORMANCE] – analyze and compare two versions of SQL performance data. The performance data is generated by test-executing or generating explain plan of the SQL statements. Use
this option when two executions of type EXPLAIN_PLAN or TEST_EXECUTE already exist in the task
CONVERT SQLSET – used to read the statistics captured in a SQL Tuning Set and model them as a task execution. This can be used when you wish to avoid executing the SQL statements because
valid data for the experiment already exists in the SQL Tuning Set.
For 9i Upgrade to 10g
exec dbms_stats.gather_system_stats(gathering_mode=>'NOWORKLOAD'); alter system set "_optim_peek_user_binds"=false; ==> 禁用BIND PEEK特性,該特性在10g中有 exec DBMS_STATS.SET_PARAM( 'method_opt','FOR ALL COLUMNS SIZE 1' ); commit; 9i ?/rdbms/admin/dbmssupp exec dbms_support.start_trace(binds=>TRUE, waits=> FALSE); exec dbms_support.stop_trace; exec dbms_support.start_trace_in_session(sid=>sid,serial=>ser, binds=>TRUE, waits=>FALSE); select sid,serial# from v$SESSION WHERE ... ; exec dbms_support.stop_trace_in_session(sid=>SID,serial=>ser); create table mapping_table tablespace USERS as select object_id id, owner, substr(object_name, 1, 30) name from dba_objects where object_type not in ('CONSUMER GROUP', 'EVALUATION CONTEXT', 'FUNCTION', 'INDEXTYPE', 'JAVA CLASS', 'JAVA DATA', 'JAVA RESOURCE', 'LIBRARY', 'LOB', 'OPERATOR', 'PACKAGE', 'PACKAGE BODY', 'PROCEDURE', 'QUEUE', 'RESOURCE PLAN', 'SYNONYM', 'TRIGGER', 'TYPE', 'TYPE BODY') union all select user_id id, username owner, null name from dba_users; declare mycur dbms_sqltune.sqlset_cursor; begin dbms_sqltune.create_sqlset('9i_prod_wkld'); open mycur for select value(p) from table(dbms_sqltune.select_sql_trace( directory=>'SPADIR', file_name=>'%trc', mapping_table_name => 'MAPPING_TABLE', select_mode => dbms_sqltune.single_execution)) p; dbms_sqltune.load_sqlset( sqlset_name => '9i_prod_wkld', populate_cursor => mycur, commit_rows => 1000); close mycur; end; / create user spadba identified by oracle; grant dba to spadba; grant all on dbms_sqlpa to spadba; create public database link to10g connect to spadba identified by oracle using 'STRINGS'; var sts_task varchar2(64); exec :sts_task:= dbms_sqlpa.create_analysis_task(task_name => '9i_11g_spa1',description => 'experiment for 9i to 11gR2 upgrade',sqlset_name=> '9i_prod_wkld'); var exe_task varchar2(64); exec :exe_task:=dbms_sqlpa.execute_analysis_task(task_name=>'9i_11g_spa1',execution_name=>'9i_trail1',execution_type=>'CONVERT SQLSET',execution_desc=>'9i sql trail generated from sts'); dbms_sqlpa.execute_analysis_task(task_name=>'9i_11g_spa1',execution_name=>'10g_trail1',execution_type=>'TEST EXECUTE',execution_desc=>'10g trail test',- execution_params=>dbms_advisor.arglist('DATABASE_LINK','DBLINKNAME')); select sofar,totalwork from V$ADVISOR_PROGRESS where task_id=<TID>;
報錯:
begin dbms_sqlpa.execute_analysis_task(task_name => 'STS_EGIS_NBU001',execution_type => 'TEST EXECUTE',execution_name => 'exec401',execution_params =>dbms_advisor.argList('DATABASE_LINK','TO_EGISCOW','EXECUTE_COUNT',3) ,execution_desc =>'remote executeion on 10g' ); end; ORA-00001: 違反唯一約束條件 (SYS.WRI$_ADV_SQLT_PLANS_PK) ORA-06512: 在 "SYS.PRVT_ADVISOR", line 2738 ORA-06512: 在 "SYS.DBMS_ADVISOR", line 241 ORA-06512: 在 "SYS.DBMS_SQLPA", line 342 ORA-06512: 在 "SYS.DBMS_SQLPA", line 359 ORA-06512: 在 line 3
SOLUTION
In 11.2.0.1, Patch 8868231 should fixmost of the problems associated with this error. This fix isincluded in 11.2.0.2 onwards. The error can also be related to a sql statementbeing captured that is executing an "EXPLAIN PLAN for SQL" To identify these sql statement within the tuningset run:-
SELECT sql_id, sql_text, sqlset_owner, sqlset_name FROM dba_sqlset_statements WHERE sqlset_name='&TUNING_SET_NAME' AND upper(sql_text) like 'EXPLAIN%'
A problem "Explain Plan for" Sqlstatement can be removed from a sqlset using the following command.
BEGIN DBMS_SQLTUNE.DELETE_SQLSET( sqlset_name => '&TUNING_SET_NAME',basic_filter => 'sql_id = ''&sql_id'''); END; /