2009년 8월 11일 화요일

ABAP 효과적인 코딩 기법2

1.11 WHERE 없는 SELECT 구문은 피하라.

- 아래와 같이 WHERE 조건 없이 SELECT 구문을 사용하는 것은 매우 위험하다.

SELECT col1 col2 … INTO … FROM vbak.

PERFORM cal_rtn.

ENDSELECT.

- 특히 다음과 같이 빠른 속도로 크기가 증가하는 테이블에는 절대로 사용하지 말 것

- BKPF, BSEG, COBK, COEP, LIPK, LIPS, MKPF, MSEG, VBAK, VBAP, VBPA, VBFA

- 테이블의 모든 데이터를 읽어 작업을 수행하려 한다면 다음과 같이 EXEC SQL 구문을 이용한 native sql을 구사하여 Application Server를 Bypass 하도록 한다. 그렇지 않으면 Application Server가 Where 절에 MANDT 조건을 붙여, Full Table Scan이 되지 않고 인덱스를 이용하게 되어 최악의 결과를 초래하게 된다.

EXEC SQL.

SELECT /* rule */

Vbeln INTO : ivbak-vbeln

FROM vbak

WHERE mandt || ‘’ =: sy-mandt

ENDEXEC.

2 DML 구문 최적화
2.1 효과적인 UPDATE 기법

- SELECT 와 ENDSELECT 사이에서 순환을 하면서 UPDATE 하는 형태는 아래와 같이 WHERE 절을 이용하여 개선할 수 있다.

*-- 개선 전.

PARAMETES : pa_vkbur LIKE zvbak-vkbur.

SELECT-OPTIONS : so_vbeln FOR zvbak-vbeln.

SELECT * FROM zvbak WHERE vbeln IN so_vbeln.

zvbak-vkbur = pa_vkbur.

UPDATE zvbak.

EDNSELECT.

*----------------------------------------------------------------------*

*-- 개선 후.

UPDATE zvbak SET vkbur = pa_vkbur

WHERE vbeln IN so_vbeln.

IF sy-subrc = 0.

COMMIT WORK.

ELSE.

ROLLBACK WORK.

ENDIF.

- zvbak 1000건을 대상으로 한 결과는 다음과 같다.

SELECT .. UPDATE .. ENDSELECT. à 1.8초

UPDATE .. SET à 0.3초

- 위의 예제에서 COMMIT WORK 또는 ROLLBACK WORK 구문은 논리적인 작업 단위가 끝나면 반드시 기술해 주는 것을 잊지 말자. COMMIT WORK나 ROLLBACK WORK를 빠뜨리면 DB Server가 수정 정보를 계속 rollback segment에 가지고 있어야 하기 때문에 System에 overload로 계속 남아있게 된다.

2.2 효과적인 INSERT 기법

- 데이터를 테이블에 INSERT 하고자 할 경우, LOOP를 돌면서 처리하는 것보다 아래의 예처럼 한꺼번에 INSERT 하면 효과적이다.

*-- 개선 전.

LOOP at it.

MOVE it TO z100.

INSERT z100.

ENDLOOP.

*----------------------------------------------------------------------*

*-- 개선 후.

INSERT z100 FROM TABLE it.

- 아래 결과는 건수 당 테스트 결과이다.

- 1,000건 입력 시.

한 건씩 : 2.58초

한꺼번에 : 0.72초

- 5,000건 입력 시.

한 건씩 : 9.66초

한꺼번에 : 1.59초

- 10,000건 입력 시.

한 건씩 : 20.00초

한꺼번에 : 2.47초

2.3 효과적인 DELETE 기법

- SELECT 와 ENDSELECT 사이에서 순환을 하면서 DELETE 하는 형태는 아래와 같이 WHERE 절을 이용하여 개선할 수 있다.

*-- 개선 전.

SELECT-OPTIONS : so_vbeln FOR zvbak-vbeln.

SELECT * FROM zvbak WHERE vbeln IN so_vbeln.

DELETE zvbak.

EDNSELECT.

*----------------------------------------------------------------------*

*-- 개선 후.

DELETE FROM zvbak WHERE vbeln IN so_vbeln.

IF sy-subrc = 0.

COMMIT WORK.

ELSE.

ROLLBACK WORK.

ENDIF.

- zvbak 1000건을 대상으로 한 결과는 다음과 같다.

SELECT .. DELETE .. ENDSELECT. à 3.0초

DELETE FROM à 1.2초

- 개선 전 코딩은 거의 최악의 코딩이다. 개선 전 경우 DB Server는 대상 데이터를 찾아서 모두 Application Server로 보낸다. 데이터를 받은 Application Server는 아무 일도 하지 않고, 받은 데이터를 다시 DB Server로 보내고, DB Server에서는 이 데이터를 삭제한다.

- 그러나 개선 후의 경우는 데이터의 발췌 및 삭제 작업이 DB Server에서만 발생하게 되므로, Application Server와 DB Server사이에 데이터 전송 작업이 전혀 일어나지 않는다.

3 효과적인 Internal Table 작업
3.1 Nested LOOP 처리

- Nested LOOP는 BINARY SEARCH를 이용하여 아래와 같이 개선할 수 있다.

DATA : ivbak LIKE VBAK OCCURS 0,

Ivbap LIKE VBAP OCCURS 0.

SORT : ivbaK BY vebln, ivbap BY vbeln.

*-- 개선 전.

LOOP AT ivbak.

LOOP AT ivbap WHERE vbeln = ivbak-vbeln.

WRITE : / …

ENDLOOP.

ENDLOOP.

*-- 개선 후.

LOOP AT ivbak.

“ Work Area에 아무 값도 넘기지 않음. Sy-subrc, sy-tabix를 설정하기 위함.

READ TABLE ivbap WITH KEY vbeln = ivbak-vbeln

BINARY SEARCH TRASPORTING NO FIELDS.

LOOP AT ivbap FROM sy-tabix.

IF ivbap-vbeln <> ivbak-vbeln. EXIT. ENDIF.

WRITE : /…

ENDLOOP.

ENDLOOP.

- Ivbak : 5,000 ivbap : 20,000 일 때.

Nested LOOP with WHERE : 5분.

LOOP/READ BINARY SEARCH/LOOP : 15초.

3.2 효과적인 LOOP 처리

- 특정 조건을 만족하는 데이터가 몇 건인지를 알고 싶은 경우에는 다음과 같이 한다.

LOOP AT it1 TRANSPORTING NO FIELDS

WHERE bname = ‘smith’.

ADD 1 TO counter.

ENDLOOP.

- 특정 조건을 만족시키는 데이터가 있는지 알고 싶다면 아래와 같이 하라.

LOOP AT it1 TRANSPORTING NO FIELDS

WHERE vbeln > ‘003000000100’.

EXIT.

ENDLOOP.

-

3.3 내부 테이블 간 데이터 복사

- 동일한 구조를 가지는 두 개의 내부 테이블 간에 서로 데이터를 복사하고자 할 경우 아래와 같이 한다.

DATA : it1 LIKE eban OCCURS 100 WITH HEADER LINE,

It2 LIKE eban OCCURS 100 WITH HEADER LINE.

*-- 개선 전.

REFRESH it2.

LOOP AT it1.

MOVE it1 TO it2.

APPEND it2.

ENDLOOP.

*-- 개선 후.

It2[] = it1[].

3.4 내부 테이블의 데이터 APPEND

- 동일한 구조를 가지는 두 개의 내부 테이블간에 서로 데이터를 APPEND 하고자 할 경우에는 아래와 같이 개선한다.

DATA : it1 LIKE eban OCCURS 100 WITH HEADER LINE,

It2 LIKE eban OCCURS 100 WITH HEADER LINE.

*-- 개선 전.

LOOP AT it1.

MOVE it1 TO it2.

APPEND it2.

ENDLOOP.

*-- 개선 후.

APPEND LINES OF it1 TO it2.

3.5 내부 테이블의 데이터 삭제

- 여러 건의 데이터를 내부 테이블에서 삭제하고자 할 경우 LOOP를 돌지 말고 아래와 같이 한다.

*-- 개선 전.

LOOP AT ivbak WHERE bname = ‘smith’.

DELETE ivbak.

ENDLOOP.

*-- 개선 후.

DELETE ivbak WHERE bname = ‘smith’.

3.6 내부 테이블의 중복 데이터 삭제

DELETE ADJACENT DUPLICATES FROM itab [COMPARING field1 field2…].

- 위 방법을 사용하기 위해서는 비교조건 필드를 기준으로 정렬되어 있어야 한다. 비교조건이 없다면, 모든 필드로 정렬되어 있어야 한다.

Technorati 태그:

댓글 없음:

댓글 쓰기