oracle update 처리시 일부 컬럼 과 전체 컬럼 update 처리시 처리 로직 영향도 0 5 4,171

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; 

by jkson [2017.02.07 17:39:34]

트리거에서 update 컬럼 지정 가능한데(BEFORE/AFTER UPDATE OF 컬럼들) 전체 컬럼 UPDATE 처리해놓으시면 실제 트리거를 실행하지 않아도 될 때 트리거를 실행하게 될 거구요.

또한 기존 정보값을 받아오려면 SELECT가 한 번 필요할 거구요. 아니면 기존에 LOAD되어있는 프로그램단 데이터를 가지고와서 UPDATE해야 하는데 해당 데이터를 유저가 UPDATE하기 전에

다른 유저가 변경했다면 다른 유저의 변경분은 무효가 될 거구요..

굳이 왜 전체 컬럼 UPDATE를 하시려고 하는지요?

 


by 박상현 [2017.02.07 18:22:16]

배치 와 같은 대량건을 처리할 내용은 아닙니다. 

 어플리케이션 개발시 하이버네이트 와 같은 ORM 툴을 사용해야 하나
 프로젝트 여건상 일괄된 방법으로 처리하고자 생각해낸 방법입니다.  

 어플리케이션 이 동시성에 대한 부분은 처리하고 UPDATE 구문 처리시 위 문의 내용처럼 DB 영향도에 대한 부분이 작으면 
 전체 업데이트로 비지니스 로직을 처리하려 생각해낸 방법입니다.


by jkson [2017.02.07 18:42:01]

오라클 내부의 I/O처리는 어차피 블록단위로 이루어지니 크게 영향이 없을 것 같기도 하지만..

실제로 클라이언트단에서 오라클 서버로 기존 데이터 정보까지 왔다갔다 해야하고

굳이 배치 작업이 아니더라도 단 건이 모여서 전체가 되는 거라 성능상 좋을 것 같지는 않은데

다른 분들 의견은 어떠신지 궁금하네요.


by jkson [2017.02.07 19:06:58]
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도 많이 늘어납니다.

오라늘 내부적으로 하는 일의 량이 늘어난다고 추측해볼 수도 있을 것 같아요


by 박상현 [2017.02.08 09:19:10]

확인 고맙습니다. 

 수고하세요. 

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입