3. Discussion 대부분의 대용량 테이블에 대한 빠른 DML 처리는 PARALLEL 설정을 사용한다. 하지만 해당 테이블에 TRIGGER가 걸려있거나 ONLINE 사용중인 테이블은 이에 대한 부담이 크다. 이런 상황인 경우에 SQL을 일일이 만들어서 특정 범위를 반복적으로 DML을 수행하는 경우가 있는데 작업자는 무한적 앉아서 엔터돌이를 해야 하는 걸까. 좀 더 생각을 한 사람은 특정범위를 기준으로 PL/SQL을 통해 한 번에 작업을 한다. 그러나. 문제는 현재 이 작업이 어느 정도 수행이 되었는지를 모르기 때문에 재 작업의 부담도 크고 매우 답답함을 느낀다. 다음의 내용은 이런 경우에 활용 가능한 TIP이다.
4. 구조설계 1. 한번에 대용량 처리가 불가능하다면 처리하고자 하는 데이터의 기준범위를 설정한다.5천만건을UPDATE해야하는데 해당 테이블에 트리거가 걸려있다.테스트를 해보니 대략 1만건 정도를 한번에 처리하는 것은 큰 부담이 없다고 판단되었다. 2. FOR LOOP를 통해 1만 * ? = 5천만을 LOOP할 수 있는 구조를 만든다 i * j = 5000만
5. PACKAGE를 활용 PACKAGE의 인수가 V$SESSION에 나타난다 SELECT SID, MODULE, ACTION FROM V$SESSION WHERE SID = ?
6. DML작성 EX. UPDATABLE JOIN 활용의 예 UPDATE 대상범위를 활용 하기 위해 “B”집합에 “ROWNUM”을 활용한 RNUM 속성과 A 테이블 ROWID를RID 속성으로 미리 만들어 둔다 i, j 를 활용하여 업데이트 범위를 “1만”건 단위로 균일하게 처리할 수 있도록 조건을 추가하고 작업이 끝나면 j 를 증가시켜 다음 범위의 시작점을 초기화 시킨다
7. 예제 DECLARE iinteger; j integer; BEGIN j := 0; for i in 1..5000 loop DBMS_APPLICATION_INFO.SET_MODULE('업데이트 진행중: CUSTOMER', 'NOW : ' || (j+1)); UPDATE ( SELECT A.* , DECODE(B.MNFRM_RTRN_IND_CD,'P','C',B.MNFRM_RTRN_IND_CD) MNFRM_RTRN_IND_CD_NEW, DECODE(B.BTRY_RTRN_IND_CD,'P','C',B.BTRY_RTRN_IND_CD) BTRY_RTRN_IND_CD_NEW, DECODE(B.CHREQP_RTRN_IND_CD,'P','C',B.CHREQP_RTRN_IND_CD) CHREQP_RTRN_IND_CD_NEW FROM CUSTOMER A, CUSTOMER_HIST B WHERE A.ROWID = B.RID AND RNUM BETWEEN (j + 1) AND (10000 * i) ) X SET MNFRM_RTRN_IND_CD=MNFRM_RTRN_IND_CD_NEW, BTRY_RTRN_IND_CD=BTRY_RTRN_IND_CD_NEW; j := 10000 * i; COMMIT; end loop; end; / SQL> 위 BLOCK을 수행하기 전에 SID를 먼저 확인한 후 작업을 진행한다
8. MONITORING SQL> SELECT SID, MODULE, ACTION FROM V$SESSION WHERE SID = ? 수행결과 SID MODULE ACTION ---- --------------------------------- ---------------- 18 업데이트 진행중: CUSTOMER NOW : 40000 1 row selected. SQL>
9. TIP2 자신의 SID를 모르는 경우 작업도구에서 SID를 알 수 없으면 .. 다음의 SQL을 활용한다 SQL> SELECT SID FROM V$SESSION WHERE AUDSID = USERENV('SESSIONID') ; SID --- 18 1 row selected. SQL> 단, DBA를 통해 V$SESSION에 대한 조회 권한과 관련 PACKAGE 수행권한을 획득해야 한다