by 박상현 [Oracle 기초] update 속도 [2017.02.07 17:19:57]
안녕하세요
데이터 변경시 변경이력에 해당하는 컬럼만을 수정하는 update 구문과
해당 로우 정보를 전체를 update 구문
속도 차이가 및 내부적으로 처리하는 로직이 차이가 있을가요 ?
만약 전체 컬컬정보를 업데이트 처리시 내부적으로 인덱스 ,트리거, 포링키 등 변경이력에 따른 불필요한 이벤트가 발생할까요 ?
전체및 일부에 update 에 따른 이벤트 내용이 동일하다면 구지 모든 처리 로직을 일괄 업데이트를 적용하려 합니다.
1) CASE
- 변경 내용에 해당 하는 컬럼만을 업데이트 처리시
UPDATE
SET col1 = '변경 0'
, col3 = '변경 1'
, col5 = '변경 2'
WEHRE SEQ = 9999;
2) CASE
- 로우정보에 변경이 발생하면 전체 컬럼을 UPDATE 처리시
UPDATE
SET col1 = '변경 0'
, col2 = '기존정보'
, col3 = '변경 2'
, col4 = '기존정보'
, col5 = '변경 4'
, col6 = '기존정보
, col7 = '기존정보
, col8 = '기존정보'
WEHRE SEQ = 9999;
CREATE TABLE TMP_20170207 ( ACOL VARCHAR2(10) ,BCOL VARCHAR2(10) ,CCOL VARCHAR2(10) ,DCOL VARCHAR2(10) ,ECOL VARCHAR2(10) ,FCOL VARCHAR2(10) ,GCOL VARCHAR2(10) ,HCOL VARCHAR2(10) ,ICOL VARCHAR2(10) ,JCOL VARCHAR2(10) ,KCOL VARCHAR2(10) ,LCOL VARCHAR2(10) ,MCOL VARCHAR2(10) ,NCOL VARCHAR2(10) ,OCOL VARCHAR2(10) ,PCOL VARCHAR2(10) ) INSERT INTO TMP_20170207 VALUES ('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P') INSERT INTO TMP_20170207 SELECT * FROM TMP_20170207 CONNECT BY LEVEL <= 100000 --단일 컬럼 UPDATE한 경우 UPDATE TMP_20170207 SET ACOL = '1' PARSE #11529215044982024512:c=0,e=108,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=526477053,tim=22979611848543 WAIT #11529215044982024512: nam='Disk file operations I/O' ela= 64 FileOperation=2 fileno=3 filetype=2 obj#=-1 tim=22979611849640 EXEC #11529215044982024512:c=60000,e=61126,p=0,cr=570,cu=168,mis=0,r=10001,dep=0,og=1,plh=526477053,tim=22979611909799 STAT #11529215044982024512 id=1 cnt=0 pid=0 pos=1 obj=0 op='UPDATE TMP_20170207 (cr=570 pr=0 pw=0 time=61046 us)' STAT #11529215044982024512 id=2 cnt=10001 pid=1 pos=1 obj=370029 op='TABLE ACCESS FULL TMP_20170207 (cr=570 pr=0 pw=0 time=7046 us cost=2 size=7 card=1)' WAIT #11529215044982024512: nam='SQL*Net message to client' ela= 2 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=22979611909926 Rows Row Source Operation ------- --------------------------------------------------- 0 UPDATE TMP_20170207 (cr=570 pr=0 pw=0 time=61080 us) 10001 TABLE ACCESS FULL TMP_20170207 (cr=570 pr=0 pw=0 time=7798 us cost=2 size=7 card=1) --전체 컬럼 UPDATE한 경우 UPDATE TMP_20170207 SET ACOL = '1' ,BCOL = 'B' ,CCOL = 'C' ,DCOL = 'D' ,ECOL = 'E' ,FCOL = 'F' ,GCOL = 'G' ,HCOL = 'H' ,ICOL = 'I' ,JCOL = 'J' ,KCOL = 'K' ,LCOL = 'L' ,MCOL = 'M' ,NCOL = 'N' ,OCOL = 'O' ,PCOL = 'P' PARSE #11529215044982074648:c=0,e=58,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=526477053,tim=22979614396134 EXEC #11529215044982074648:c=100000,e=88773,p=0,cr=570,cu=258,mis=0,r=10001,dep=0,og=1,plh=526477053,tim=22979614485101 STAT #11529215044982074648 id=1 cnt=0 pid=0 pos=1 obj=0 op='UPDATE TMP_20170207 (cr=570 pr=0 pw=0 time=88726 us)' STAT #11529215044982074648 id=2 cnt=10001 pid=1 pos=1 obj=370029 op='TABLE ACCESS FULL TMP_20170207 (cr=570 pr=0 pw=0 time=7771 us cost=156 size=991088 card=8849)' WAIT #11529215044982074648: nam='SQL*Net message to client' ela= 1 driver id=1413697536 #bytes=1 p3=0 obj#=-1 tim=22979614485209 Rows Row Source Operation ------- --------------------------------------------------- 0 UPDATE TMP_20170207 (cr=570 pr=0 pw=0 time=87770 us) 10001 TABLE ACCESS FULL TMP_20170207 (cr=570 pr=0 pw=0 time=7138 us cost=156 size=991088 card=8849)
살짝 테스트해봤는데 ACCESS하는 블록수는 동일하지만 COST가 훨씬 높아지고 SIZE도 많이 늘어납니다.
오라늘 내부적으로 하는 일의 량이 늘어난다고 추측해볼 수도 있을 것 같아요