客户的每小时redolog日志量大,配合AWR和LOGMINER检查发现是由一条update语句引起。这条语句大概每小时执行80次左右,不仅产生了大量的重做日志,而且逻辑读也很高。

语句类似update tb_test_log set object_id=1 where owner='SYS',是对表tb_test_log按一定的频率,把满足条件owner='SYS'的记录中的object_id修改为1,而且满足条件的记录占了整个表的一半左右。但实际上在每次更新时,满足条件owner='SYS'的记录中绝大部分object_id已经是1.

以下尝试优化:

DB Version:12.1.0.2.0

OS:centos 6.6

#建测试表create table tb_test_log tablespace users as select * from dba_objects;

insert into tb_test_log select * from tb_test_log;

commit;

insert into tb_test_log select * from tb_test_log;

commit;

insert into tb_test_log select * from tb_test_log;

commit;

#查看测试表的大小,大概100MBselect bytes from dba_segments where segment_name=upper('tb_test_log');

/*

BYTES

109051904

*/

#满足条件owner='SYS'的记录大概占了46%

select count(decode(owner,'SYS',1,null))/count(1) from tb_test_log;

/*

0.461732733062479

*/

#优化前SQL

update tb_test_log set object_id=1 where owner='SYS';

#新建会话统计数据记录表,用于后面的重做日志和逻辑读的计算

declare

v_count number;

begin

select count(1) into v_count from dba_tables where table_name='T_STAT_TEMP';

if v_count=1 then

execute immediate 'truncate table t_stat_temp';

else

execute immediate 'create table t_stat_temp(snap_date date,name varchar2(100),value int)';

end if;

end;

会话1:

#查看会话1的会话ID

select sid from v$mystat where rownum<=1;

/*

SID

35

*/

会话2:

#插入会话1当前的重做日志和逻辑读的统计数据

insert into t_stat_temp

select sysdate,a.name,b.value

from v$statname a,v$sesstat b

where a.statistic#=b.statistic# and b.sid=35

and a.name in ('redo size','session logical reads');

commit;

#DIFF是会话1产生的重做日志和逻辑读的量

select name,min(value) begin_value,max(value) end_value,max(value)-min(value) diff

from (select * from t_stat_temp order by snap_date desc)

where rownum<=4

group by name;

/*

NAME    BEGIN_VALUE    END_VALUE    DIFF

redo size    736    736    0

session logical reads    1463    1463    0

*/

#后续会话2都是执行上面相同的插入和查询语句,省略语句,只显示查询结果

会话1:

#会话1执行优化前的更新语句

update tb_test_log set object_id=1 where owner='SYS';

commit;

会话2:

#会话1此次执行更新语句后,redo size产生168611404,session logical reads消耗1057915

/*

NAME    BEGIN_VALUE    END_VALUE    DIFF

redo size    736    168612140    168611404

session logical reads    1463    1059378    1057915

*/

会话1:

#会话1执行优化前的更新语句

update tb_test_log set object_id=1 where owner='SYS';

commit;

会话2:

#会话1此次执行更新语句后,redo size产生108994644,session logical reads消耗718610

/*

NAME    BEGIN_VALUE    END_VALUE    DIFF

redo size    168612140    277606784    108994644

session logical reads    1059378    1777988    718610

*/

会话1:

#会话1执行优化前的更新语句

update tb_test_log set object_id=1 where owner='SYS';

commit;

会话2:

#会话1此次执行更新语句后,redo size产生112071424,session logical reads消耗731397

/*

NAME    BEGIN_VALUE    END_VALUE    DIFF

redo size    277606784    389678208    112071424

session logical reads    1777988    2509385    731397

*/

会话1:

#会话1执行优化前的更新语句

update tb_test_log set object_id=1 where owner='SYS';

commit;

会话2:

#会话1此次执行更新语句后,redo size产生131894432,session logical reads消耗759343

/*

NAME    BEGIN_VALUE    END_VALUE    DIFF

redo size    389678208    521572640    131894432

session logical reads    2509385    3268728    759343

*/

会话1:

#会话1执行优化前的更新语句

update tb_test_log set object_id=1 where owner='SYS';

commit;

会话2:

#会话1此次执行更新语句后,redo size产生133580596,session logical reads消耗762190

/*

NAME    BEGIN_VALUE    END_VALUE    DIFF

redo size    521572640    655153236    133580596

session logical reads    3268728    4030918    762190

*/

小结:优化前,每次更新表中46%左右的数据,重做日志产生量大概是100MB+,逻辑读大概是700000+。

优化1:

根据SQL逻辑,增加过滤条件object_id!=1,原语句逻辑不变。

会话1:

#会话1执行优化1的更新语句

update tb_test_log set object_id=1 where owner='SYS' and object_id!=1;

commit;

会话2:

#会话1此次执行更新语句后,redo size产生827112,session logical reads消耗22835

/*

NAME    BEGIN_VALUE    END_VALUE    DIFF

redo size    655153236    655980348    827112

session logical reads    4030918    4053753    22835

*/

会话1:

#会话1执行优化1的更新语句

update tb_test_log set object_id=1 where owner='SYS' and object_id!=1;

commit;

会话2:

#会话1此次执行更新语句后,redo size产生340,session logical reads消耗12413

/*

NAME    BEGIN_VALUE    END_VALUE    DIFF

redo size    655980348    655980688    340

session logical reads    4053753    4066166    12413

*/

会话1:

#会话1执行优化1的更新语句

update tb_test_log set object_id=1 where owner='SYS' and object_id!=1;

commit;

会话2:

#会话1此次执行更新语句后,redo size产生340,session logical reads消耗12413

/*

NAME    BEGIN_VALUE    END_VALUE    DIFF

redo size    655980688    655981028    340

session logical reads    4066166    4078579    12413

*/

小结:优化1,每次基本上不更新表中数据,重做日志产生量大概是300+,逻辑读大概是10000+。

优化2:

根据SQL逻辑,增加过滤条件decode(object_id,1,null,'1')='1',并增加索引tb_test_log(owner,decode(object_id,1,null,'1')),原语句逻辑不变。

会话3:

#新建索引

create index idx_tb_test_log_01 on tb_test_log(owner,decode(object_id,1,null,'1'))  tablespace users;

会话1:

#会话1执行优化2的更新语句

update tb_test_log set object_id=1 where owner='SYS' and decode(object_id,1,null,'1')='1';

commit;

会话2:

#会话1此次执行更新语句后,redo size产生384,session logical reads消耗11214

/*

NAME    BEGIN_VALUE    END_VALUE    DIFF

redo size    655981028    655981412    384

session logical reads    4078579    4089793    11214

*/

会话1:

#会话1执行优化2的更新语句

update tb_test_log set object_id=1 where owner='SYS' and decode(object_id,1,null,'1')='1';

commit;

会话2:

#会话1此次执行更新语句后,redo size产生384,session logical reads消耗6

/*

NAME    BEGIN_VALUE    END_VALUE    DIFF

redo size    655981412    655981796    384

session logical reads    4089793    4089799    6

*/

会话1:

#会话1执行优化2的更新语句

update tb_test_log set object_id=1 where owner='SYS' and decode(object_id,1,null,'1')='1';

commit;

会话2:

#会话1此次执行更新语句后,redo size产生384,session logical reads消耗5

/*

NAME    BEGIN_VALUE    END_VALUE    DIFF

redo size    655981796    655982180    384

session logical reads    4089799    4089804    5

*/

小结:优化2,每次基本上不更新表中数据,重做日志产生量大概是300+,逻辑读大概是5+。

总结:

1.根据SQL逻辑,增加过滤条件object_id!=1,原语句逻辑不变,大幅度降低了重做日志的产生量。

2.根据SQL逻辑,增加过滤条件decode(object_id,1,null,'1')='1',并增加索引tb_test_log(owner,decode(object_id,1,null,'1')),原语句逻辑不变,大幅度降低了重做日志的产生量和逻辑读。

3.类似问题的DELETE语句也可以从此方法中受益。

oracle更新预计需要多久,oracle update操作的优化一例相关推荐

  1. oracle 更新语句不生效,Oracle存储过程执行update语句不报错不生效问题

    转载链接:http://lin49940.iteye.com/blog/466626 今天一个同事写oracle 的存储过程遇到了一个问题, 他在里面update 操作不能完成更新的操作, 但是又不会 ...

  2. oracle更新报错14402,Oracle GoldenGate 系列:Replicat 进程遇 OCI Error ORA-14402 错误解决办法...

    生产环境发票管理库到总局主数据库 Replicat 进程因报如下错误 Abended: 2013-04-25 07:59:50  WARNING OGG-00869  OCI Error ORA-14 ...

  3. oracle更新快捷方式的错误,oracle 11g数据库启动错误总结

    1.启动数据库时提示ORA-00845: MEMORY_TARGET not supported on this system (在oracle 11g中新增的内存自动管理的参数MEMORY_TARG ...

  4. mysql rr 更新失败_RR 级别下 update 操作的是快照读还是当前读?

    我们知道在 RR 级别下,重复的 select 操作,读取的值都会是一致的.即便在两次 select 操作的中间,有一个事务 B 修改了值,但是在事务 A 中 select 读取的值还是一致的. 那么 ...

  5. oracle更新语句怎么撤回,oracle撤回UPdate误操作的数据

    oracle提供了一种闪回的方法,可以将某个时间的数据给还原回来 方法如下: 1.select * from table as of timestamp to_timestamp('2016-10-1 ...

  6. oracle更新数据没反应,ORACLE更新数据时如果有就更新没有就插入

    SQL写法: begin update table_name set salary = 10000 where emp_id = 5; if sql%notfound then insert into ...

  7. oracle启动crs要多久,ORACLE RAC crs 无法启动

    OS: ORACLE LINUX 5.7 DB: 11.2.0.3 RAC:YES 故障: 1.两节点RAC,节点分别为linuxdb1.linuxdb2,其中节点linuxdb2服务器出现故障,无法 ...

  8. Oracle数据导入要多久,oracle数据库备份导入要注意的几个问题

    oracle数据库备份导入要注意的几个问题 (1)oracle数据库备份的导入对数据库的版本有要求,也即源数据库(导出产生备份的数据库)的版本要和目标数据库(导入数据库)的版本一致,否则可能导致导入失 ...

  9. oracle能闪回多久,oracle 闪回基于时间的恢复

    下面这篇文章是闪会基于时间点的恢复,可以恢复误删除的数据,刚好今天有客户遇到这样的案例 Microsoft Windows [版本 5.2.3790] (C) 版权所有 1985-2003 Micro ...

最新文章

  1. 微软洪小文:制造业是最先享受AI成果的领域
  2. 开源路由器爱好者迎来利好 Linksys不变
  3. WebPack在多页应用项目中的探索
  4. ruby 嵌套函数_Ruby嵌套直到循环带有示例
  5. JavaScript高级程序设计(2)在HTML中使用JavaScript
  6. datagridview的数据存取
  7. java 重量单位换算_用java创建一个可以换算长度单位的length类,将某种长度单位进行数值间的转换。...
  8. Win10家庭版远程桌面工具RDP Wrapper
  9. 国内的点对点聊天工具鱼信Fishchat怎么用?
  10. 大数据认知实习的实习目的_如何在数据实习中取得成功
  11. 全民主公2怎么在电脑上玩 全民主公2安卓模拟器玩法教程
  12. webgl天空盒边界缝隙_基于webGL技术的3D库ThingJS支持天空盒技术实现
  13. excel设置数据点的标记格式
  14. 页面置换算法-LRU
  15. GitHub 热点速览 Vol.13:近 40k star 计算机论文项目再霸 GitHub Trending 榜
  16. matlab 小波的分解与重构
  17. python有道翻译接口-Python调用有道翻译api实现翻译
  18. VBA颜色转换 中英互译
  19. 为什么需要每年重新签发SSL证书?
  20. Putty完全使用方法

热门文章

  1. c语言 wifi 开发,Android WIFI Direct开发教程
  2. 墨刀 - 简单、易用的APP原型设计工具
  3. qt实现汽车销售管理系统(四)--统计数据的实现
  4. D-017 SWD硬件电路设计
  5. Allegro转PADS格式
  6. CouchDB 实现原理
  7. 微信小程序引入iconfont渲染层网络层错误
  8. AnyChart控件
  9. 动态加载的函数库Dynamically Loaded (DL) Libraries
  10. 奋斗吧,程序员——第三十六章 落花人独立,微雨燕双飞