溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

oracle update操作的優(yōu)化實例分析

發(fā)布時間:2022-01-15 10:19:38 來源:億速云 閱讀:330 作者:iii 欄目:關(guān)系型數(shù)據(jù)庫

本篇內(nèi)容主要講解“oracle update操作的優(yōu)化實例分析”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學(xué)習(xí)“oracle update操作的優(yōu)化實例分析”吧!

    客戶的每小時redolog日志量大,配合AWR和LOGMINER檢查發(fā)現(xiàn)是由一條update語句引起。這條語句大概每小時執(zhí)行80次左右,不僅產(chǎn)生了大量的重做日志,而且邏輯讀也很高。
    語句類似update tb_test_log set object_id=1 where owner='SYS',是對表tb_test_log按一定的頻率,把滿足條件owner='SYS'的記錄中的object_id修改為1,而且滿足條件的記錄占了整個表的一半左右。但實際上在每次更新時,滿足條件owner='SYS'的記錄中絕大部分object_id已經(jīng)是1.
以下嘗試優(yōu)化:
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
*/

#優(yōu)化前SQL
update tb_test_log set object_id=1 where owner='SYS';

#新建會話統(tǒng)計數(shù)據(jù)記錄表,用于后面的重做日志和邏輯讀的計算
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當前的重做日志和邏輯讀的統(tǒng)計數(shù)據(jù)
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產(chǎn)生的重做日志和邏輯讀的量
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
*/

#后續(xù)會話2都是執(zhí)行上面相同的插入和查詢語句,省略語句,只顯示查詢結(jié)果

會話1:
#會話1執(zhí)行優(yōu)化前的更新語句
update tb_test_log set object_id=1 where owner='SYS';
commit;
會話2:
#會話1此次執(zhí)行更新語句后,redo size產(chǎn)生168611404,session logical reads消耗1057915
/*
NAME    BEGIN_VALUE    END_VALUE    DIFF
redo size    736    168612140    168611404
session logical reads    1463    1059378    1057915
*/

會話1:
#會話1執(zhí)行優(yōu)化前的更新語句
update tb_test_log set object_id=1 where owner='SYS';
commit;
會話2:
#會話1此次執(zhí)行更新語句后,redo size產(chǎn)生108994644,session logical reads消耗718610
/*
NAME    BEGIN_VALUE    END_VALUE    DIFF
redo size    168612140    277606784    108994644
session logical reads    1059378    1777988    718610
*/

會話1:
#會話1執(zhí)行優(yōu)化前的更新語句
update tb_test_log set object_id=1 where owner='SYS';
commit;
會話2:
#會話1此次執(zhí)行更新語句后,redo size產(chǎn)生112071424,session logical reads消耗731397
/*
NAME    BEGIN_VALUE    END_VALUE    DIFF
redo size    277606784    389678208    112071424
session logical reads    1777988    2509385    731397
*/

會話1:
#會話1執(zhí)行優(yōu)化前的更新語句
update tb_test_log set object_id=1 where owner='SYS';
commit;
會話2:
#會話1此次執(zhí)行更新語句后,redo size產(chǎn)生131894432,session logical reads消耗759343
/*
NAME    BEGIN_VALUE    END_VALUE    DIFF
redo size    389678208    521572640    131894432
session logical reads    2509385    3268728    759343
*/

會話1:
#會話1執(zhí)行優(yōu)化前的更新語句
update tb_test_log set object_id=1 where owner='SYS';
commit;
會話2:
#會話1此次執(zhí)行更新語句后,redo size產(chǎn)生133580596,session logical reads消耗762190
/*
NAME    BEGIN_VALUE    END_VALUE    DIFF
redo size    521572640    655153236    133580596
session logical reads    3268728    4030918    762190
*/
小結(jié):優(yōu)化前,每次更新表中46%左右的數(shù)據(jù),重做日志產(chǎn)生量大概是100MB+,邏輯讀大概是700000+。

優(yōu)化1:
根據(jù)SQL邏輯,增加過濾條件object_id!=1,原語句邏輯不變。
會話1:
#會話1執(zhí)行優(yōu)化1的更新語句
update tb_test_log set object_id=1 where owner='SYS' and object_id!=1;
commit;
會話2:
#會話1此次執(zhí)行更新語句后,redo size產(chǎn)生827112,session logical reads消耗22835
/*
NAME    BEGIN_VALUE    END_VALUE    DIFF
redo size    655153236    655980348    827112
session logical reads    4030918    4053753    22835
*/

會話1:
#會話1執(zhí)行優(yōu)化1的更新語句
update tb_test_log set object_id=1 where owner='SYS' and object_id!=1;
commit;
會話2:
#會話1此次執(zhí)行更新語句后,redo size產(chǎn)生340,session logical reads消耗12413
/*
NAME    BEGIN_VALUE    END_VALUE    DIFF
redo size    655980348    655980688    340
session logical reads    4053753    4066166    12413
*/

會話1:
#會話1執(zhí)行優(yōu)化1的更新語句
update tb_test_log set object_id=1 where owner='SYS' and object_id!=1;
commit;
會話2:
#會話1此次執(zhí)行更新語句后,redo size產(chǎn)生340,session logical reads消耗12413
/*
NAME    BEGIN_VALUE    END_VALUE    DIFF
redo size    655980688    655981028    340
session logical reads    4066166    4078579    12413
*/
小結(jié):優(yōu)化1,每次基本上不更新表中數(shù)據(jù),重做日志產(chǎn)生量大概是300+,邏輯讀大概是10000+。

優(yōu)化2:
根據(jù)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執(zhí)行優(yōu)化2的更新語句
update tb_test_log set object_id=1 where owner='SYS' and decode(object_id,1,null,'1')='1';
commit;
會話2:
#會話1此次執(zhí)行更新語句后,redo size產(chǎn)生384,session logical reads消耗11214
/*
NAME    BEGIN_VALUE    END_VALUE    DIFF
redo size    655981028    655981412    384
session logical reads    4078579    4089793    11214
*/

會話1:
#會話1執(zhí)行優(yōu)化2的更新語句
update tb_test_log set object_id=1 where owner='SYS' and decode(object_id,1,null,'1')='1';
commit;
會話2:
#會話1此次執(zhí)行更新語句后,redo size產(chǎn)生384,session logical reads消耗6
/*
NAME    BEGIN_VALUE    END_VALUE    DIFF
redo size    655981412    655981796    384
session logical reads    4089793    4089799    6
*/

會話1:
#會話1執(zhí)行優(yōu)化2的更新語句
update tb_test_log set object_id=1 where owner='SYS' and decode(object_id,1,null,'1')='1';
commit;
會話2:
#會話1此次執(zhí)行更新語句后,redo size產(chǎn)生384,session logical reads消耗5
/*
NAME    BEGIN_VALUE    END_VALUE    DIFF
redo size    655981796    655982180    384
session logical reads    4089799    4089804    5
*/
小結(jié):優(yōu)化2,每次基本上不更新表中數(shù)據(jù),重做日志產(chǎn)生量大概是300+,邏輯讀大概是5+。

到此,相信大家對“oracle update操作的優(yōu)化實例分析”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進入相關(guān)頻道進行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI