数据库迁移,spm baseline 保持执行计划的稳定性

目前负责的数据库压力过大,要把其中一个比较核心的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/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Django数据库迁移是指在使用Django框架开发应用时,对数据库模型的变更进行同步的过程。可以通过在终端运行命令`python manage.py makemigrations`来生成数据库迁移文件,并通过`python manage.py migrate`来应用这些数据库迁移文件。 为了进行数据库迁移,首先需要在项目的settings.py文件中配置数据库连接信息,包括数据库类型、数据库名称、用户名、密码、主机和端口等。例如,可以使用MySQL作为数据库并在settings.py中配置相关信息。 其次,需要在项目中新建app,并通过在settings.py文件中注册该app。然后,可以通过运行命令`python manage.py makemigrations app_name`来为该app生成数据库迁移文件。 在执行数据库迁移前,需要确保已经在数据库中创建了对应的数据库。可以通过工具如Navicat在数据库中新建数据库执行数据库迁移的命令`python manage.py migrate`会将数据库模型的变更应用到数据库中,从而实现数据库结构的更新。 当执行完成数据库迁移后,数据库就会与项目中的模型定义保持同步。这样,就可以在项目中对数据库进行操作,并确保数据库的结构和数据的一致性。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [django迁移数据库错误问题解决](https://download.csdn.net/download/weixin_38730977/12861095)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [django数据迁移](https://blog.csdn.net/lyhwhitewhale/article/details/125190719)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值