目前负责的数据库压力过大,要把其中一个比较核心的SCHEMA迁移到另一套环境里来降低压力。迁移前后的版本是一样的,都是11.1.0.7.统计信息也是通过DBMS_STATS包导出导入的,按理说,执行计划变化的可能性不大。但是为了确保执行计划不出错,打算还是折腾一把,通过11G的 SPM BASELINE在老库生成一个调优集,然后把这个调优集加载到新的数据库上的,然后通过SPM BASELINE提供的过程来为这个调优集生成BASEINE。这样就能保证这些调优集里的SQL 执行计划不发生变化,而且还可以通过SPM提供的视图来查看那些SQL在新的环境下自动的产生了一些可以改进的执行计划,如果这种改变是好的,我们可以通过BASELINE重演来接受这种改变。最后可以把没有产生执行计划改变的BAELINE删除掉。具体方案如下:
1)新创建一个SQL 调优集
exec dbms_sqltune.create_sqlset(sqlset_name=>'vodka_set');
2)为新创建的SQL 调优集加载SQL,这里可以选择加载那些SQL,本例里加载了VODKA 用户产生的,签名不是0的,BUFFER_GETS(总)大于1000的,执行次数(总)大于100的,命令类型不为INSERT的SQL
DECLARE
cur DBMS_SQLTUNE.SQLSET_CURSOR;
BEGIN
OPEN cur FOR
SELECT VALUE(P)
FROM table(DBMS_SQLTUNE.SELECT_CURSOR_CACHE('PARSING_SCHEMA_NAME=''VODKA'' and force_matching_signature<>0 and BUFFER_GETS>1000 and EXECUTIONS>100 and command_type<>2',
NULL,
NULL,
NULL,
NULL,
1,
NULL,
'ALL')) P;
DBMS_SQLTUNE.LOAD_SQLSET(sqlset_name => 'vodka_set',
populate_cursor => cur);
END;
/
3)把调优集的内容加载到一张舞台表里
exec DBMS_SQLTUNE.CREATE_STGTAB_SQLSET('WXH_TBD0931');
exec DBMS_SQLTUNE.PACK_STGTAB_SQLSET('vodka_set','SYSTEM','WXH_TBD0931','SYSTEM');
4)通过导入导出工具来把舞台表传输到新的数据库上
exp system/0o98udrft00oop file=/tmp/weixh.dmp tables=WXH_TBD0931
scp /tmp/weixh.dmp oracle@172.16.129.151:/tmp
imp system/0o98udrft00oop file=/tmp/weixh.dmp fromuser=system touser=SYSTEM
5)在新的数据库上把SQL调优集加载进来
begin
DBMS_SQLTUNE.UNPACK_STGTAB_SQLSET(sqlset_name => 'vodka_set',
sqlset_owner => 'SYSTEM',
replace => true,
staging_table_name => 'WXH_TBD0931',
staging_schema_owner => 'SYSTEM');
END;
/
6)通过SPM BASELINE的包来把SQL调优集里的SQL都批量的生成BASELINE
declare
ret number;
begin
ret := dbms_spm.load_plans_from_sqlset(sqlset_name => 'vodka_set',sqlset_owner => 'SYSTEM');
end;
/
这样做了后,就能确保数据库迁移后,两边的执行计划是一致的,不会出现性能问题。如果在新库上,ORACLE认为有更好的执行计划,会在dba_sql_plan_baselines里产生出一个origin为AUTO-CAPTURE,ACCEPTED为NO的baseline。你可以通过如下两种方法来验证到底是新产生出来的执行计划好,还是旧的好。我的例子里SQL HANDLE为'SYS_SQL_b13d37f143c8d367'的产生一个新的不可接受的执行计划。
select sql_handle,plan_name,origin,accepted from dba_sql_plan_baselines where sql_handle='SYS_SQL_b13d37f143c8d367';
SQL_HANDLE PLAN_NAME ORIGIN ACCEPT
------------------------------ ------------------------------ ---------------------------- ------
SYS_SQL_b13d37f143c8d367 SYS_SQL_PLAN_43c8d3671a342c8e AUTO-CAPTURE NO
SYS_SQL_b13d37f143c8d367 SYS_SQL_PLAN_43c8d367affaa175 MANUAL-LOAD YES
1)查看两种执行计划的差异来判断
SELECT *
FROM table(dbms_xplan.display_sql_plan_baseline(sql_handle => 'SYS_SQL_b13d37f143c8d367',
plan_name => 'SYS_SQL_PLAN_43c8d3671a342c8e'));
SQL handle: SYS_SQL_b13d37f143c8d367
SQL text: UPDATE APP_USER_LOGIN SET IS_ONLINE = 'y', LAST_REGISTER = :B6 , IP =
:B5 , ROLE_NAME = :B4 , ORG_ID = :B3 , FALSE_COUNT = 0, CHANNEL = :B2
WHERE LOGIN_ID = :B1
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
Plan name: SYS_SQL_PLAN_43c8d3671a342c8e
Enabled: YES Fixed: NO Accepted: NO Origin: AUTO-CAPTURE
--------------------------------------------------------------------------------
Plan hash value: 2701429484
----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | UPDATE STATEMENT | | 1 | 72 | 2 (0)| 00:00:01 |
| 1 | UPDATE | APP_USER_LOGIN | | | | |
|* 2 | INDEX UNIQUE SCAN| APP_USER_LOGIN_PK | 1 | 72 | 1 (0)| 00:00:01 |
----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("LOGIN_ID"=:B1)
SELECT *
FROM table(dbms_xplan.display_sql_plan_baseline(sql_handle => 'SYS_SQL_b13d37f143c8d367',
plan_name => 'SYS_SQL_PLAN_43c8d367affaa175'));
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
Plan name: SYS_SQL_PLAN_43c8d367affaa175
Enabled: YES Fixed: NO Accepted: YES Origin: MANUAL-LOAD
--------------------------------------------------------------------------------
Plan hash value: 2066069757
-------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------
| 0 | UPDATE STATEMENT | | 1 | 63 | 15 (0)| 00:00:01 |
| 1 | UPDATE | APP_USER_LOGIN | | | | |
|* 2 | TABLE ACCESS FULL| APP_USER_LOGIN | 1 | 63 | 15 (0)| 00:00:01 |
-------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter("LOGIN_ID"=:B1)
可以看到自动捕获出来的不可接受的BASELINE的执行计划比较优秀,走了索引,因此我们可以通过BASELINE重演接受它,后面会介绍怎么用BASELINE重演
2)重演BASELINE来查看两种执行计划到底哪种更好
SELECT dbms_spm.evolve_sql_plan_baseline(
sql_handle => 'SYS_SQL_b13d37f143c8d367',
plan_name => NULL,
time_limit => 10,
verify => 'yes',
commit => 'no'
)
FROM dual;
DBMS_SPM.EVOLVE_SQL_PLAN_BASELINE(SQL_HANDLE=>'SYS_SQL_B13D37F143C8D367',PLAN_NA
--------------------------------------------------------------------------------
-------------------------------------------------------------------------------
Evolve SQL Plan Baseline Report
-------------------------------------------------------------------------------
Inputs:
-------
SQL_HANDLE = SYS_SQL_b13d37f143c8d367
PLAN_NAME =
TIME_LIMIT = 10
VERIFY = yes
COMMIT = no
Plan: SYS_SQL_PLAN_43c8d3671a342c8e
-----------------------------------
Plan was verified: Time used .13 seconds.
Passed performance criterion: Compound improvement ratio >= 115.54
Baseline Plan Test Plan Improv. Ratio
------------- --------- -------------
Execution Status: COMPLETE COMPLETE
Rows Processed: 1 1
Elapsed Time(ms): 74 22 3.36
CPU Time(ms): 54 6 9
Buffer Gets: 295 2 147.5
Disk Reads: 292 2 146
Direct Writes: 0 0
Fetches: 19 2 9.5
Executions: 1 1
-------------------------------------------------------------------------------
Report Summary
-------------------------------------------------------------------------------
Number of SQL plan baselines verified: 1.
Number of SQL plan baselines evolved: 0.
可以看到如果接受这种改变的话,性能能提升很多。
接受重演
SELECT dbms_spm.evolve_sql_plan_baseline(
sql_handle => 'SYS_SQL_b13d37f143c8d367',
plan_name => NULL,
time_limit => 10,
verify => 'yes',
commit => 'yes'
)
FROM dual;
至此,这个SQL就接受了这个ORACLE自动产生的BASELINE.
最后,如果觉得必要,可以把执行计划没有发生变化的BASELINE都删除掉。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/22034023/viewspace-708263/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/22034023/viewspace-708263/