微前端架构如何改变企业的开发模式与效率提升
492
2023-11-29
本篇内容主要讲解“oracle update操作的优化实例分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“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;
#查看测试表的大小,大概100MB
select 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+。到此,相信大家对“oracle update操作的优化实例分析”有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~