oracle更新预计需要多久,oracle update操作的优化一例
客户的每小时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操作的优化一例相关推荐
- oracle 更新语句不生效,Oracle存储过程执行update语句不报错不生效问题
转载链接:http://lin49940.iteye.com/blog/466626 今天一个同事写oracle 的存储过程遇到了一个问题, 他在里面update 操作不能完成更新的操作, 但是又不会 ...
- oracle更新报错14402,Oracle GoldenGate 系列:Replicat 进程遇 OCI Error ORA-14402 错误解决办法...
生产环境发票管理库到总局主数据库 Replicat 进程因报如下错误 Abended: 2013-04-25 07:59:50 WARNING OGG-00869 OCI Error ORA-14 ...
- oracle更新快捷方式的错误,oracle 11g数据库启动错误总结
1.启动数据库时提示ORA-00845: MEMORY_TARGET not supported on this system (在oracle 11g中新增的内存自动管理的参数MEMORY_TARG ...
- mysql rr 更新失败_RR 级别下 update 操作的是快照读还是当前读?
我们知道在 RR 级别下,重复的 select 操作,读取的值都会是一致的.即便在两次 select 操作的中间,有一个事务 B 修改了值,但是在事务 A 中 select 读取的值还是一致的. 那么 ...
- oracle更新语句怎么撤回,oracle撤回UPdate误操作的数据
oracle提供了一种闪回的方法,可以将某个时间的数据给还原回来 方法如下: 1.select * from table as of timestamp to_timestamp('2016-10-1 ...
- oracle更新数据没反应,ORACLE更新数据时如果有就更新没有就插入
SQL写法: begin update table_name set salary = 10000 where emp_id = 5; if sql%notfound then insert into ...
- oracle启动crs要多久,ORACLE RAC crs 无法启动
OS: ORACLE LINUX 5.7 DB: 11.2.0.3 RAC:YES 故障: 1.两节点RAC,节点分别为linuxdb1.linuxdb2,其中节点linuxdb2服务器出现故障,无法 ...
- Oracle数据导入要多久,oracle数据库备份导入要注意的几个问题
oracle数据库备份导入要注意的几个问题 (1)oracle数据库备份的导入对数据库的版本有要求,也即源数据库(导出产生备份的数据库)的版本要和目标数据库(导入数据库)的版本一致,否则可能导致导入失 ...
- oracle能闪回多久,oracle 闪回基于时间的恢复
下面这篇文章是闪会基于时间点的恢复,可以恢复误删除的数据,刚好今天有客户遇到这样的案例 Microsoft Windows [版本 5.2.3790] (C) 版权所有 1985-2003 Micro ...
最新文章
- 微软洪小文:制造业是最先享受AI成果的领域
- 开源路由器爱好者迎来利好 Linksys不变
- WebPack在多页应用项目中的探索
- ruby 嵌套函数_Ruby嵌套直到循环带有示例
- JavaScript高级程序设计(2)在HTML中使用JavaScript
- datagridview的数据存取
- java 重量单位换算_用java创建一个可以换算长度单位的length类,将某种长度单位进行数值间的转换。...
- Win10家庭版远程桌面工具RDP Wrapper
- 国内的点对点聊天工具鱼信Fishchat怎么用?
- 大数据认知实习的实习目的_如何在数据实习中取得成功
- 全民主公2怎么在电脑上玩 全民主公2安卓模拟器玩法教程
- webgl天空盒边界缝隙_基于webGL技术的3D库ThingJS支持天空盒技术实现
- excel设置数据点的标记格式
- 页面置换算法-LRU
- GitHub 热点速览 Vol.13:近 40k star 计算机论文项目再霸 GitHub Trending 榜
- matlab 小波的分解与重构
- python有道翻译接口-Python调用有道翻译api实现翻译
- VBA颜色转换 中英互译
- 为什么需要每年重新签发SSL证书?
- Putty完全使用方法