OpenFrame VSAM 성능 최적화
본 부록에서는 OpenFrame VSAM(TSAM)의 성능을 최적화할 수 있는 방법에 대해 설명한다.
1. 개요
OpenFrame 7 VSAM(TSAM)은 JCL 유틸리티 IDCAMS 또는 커맨드 라인 툴 idcams로 정의할 수 있다.
OpenFrame 7 VSAM은 RDB 테이블로 정의되며 테이블의 구조는 ds.TSAM_RDB.COPYBOOK_PATH로 설정된 디렉터리에서 생성할 데이터셋과 같은 이름의 copybook 파일을 참조해 정의된다. 해당 copybook은 테이블 정의 및 OpenFrame 엔진 동작에서만 사용되기 때문에 마이그레이션 스키마나 사용자 프로그램의 FD 정의와 같을 필요는 없다.
필드 타입에 따라 정의되는 컬럼 타입은 다음과 같다.
필드 타입 | 컬럼 타입 | 비고 |
---|---|---|
문자(X, N) |
VARCHAR |
|
Zoned/Packed decimal, binary(COMP,COMP-4,COMP-5) |
NUMBER |
|
Float(COMP-1) |
BINARY_FLOAT |
|
Double(COMP-2) |
BINARY_DOUBLE |
|
EBCDIC(EBC) |
NVARCHAR2 |
X, A 타입에서만 사용할 수 있으며, EBCDIC 정렬을 사용하기 위해서는 EBC 타입을 사용하여야 한다. 예) PIC X(10) EBC. |
OpenFrame 7 VSAM은 사용자가 원하는 형태에 따라 데이터가 적절히 컬럼화되어 테이블에 저장되기 때문에 RDB의 이점을 최대한 활용하고 다른 현대적인 시스템 및 애플리케이션과 쉽게 연동할 수 있다는 장점이 있다.
하지만 COBOL 프로그램을 통한 입출력에서는 컬럼화된 데이터를 읽을 때 바이트 배열의 형태로 직렬화하고 쓸 때는 역직렬화하는 과정이 생기기 때문에 추가 비용이 발생한다. 따라서 실행 시간이 중요한 배치 업무의 경우 성능 최적화가 필요할 수 있다.
ds.TSAM_RDB.PRINT_DEBUG_MSG_ON 설정을 YES로 지정하면 OpenFrame 7 VSAM은 프로그램 명령에 따라 엔진에서 요청하는 SQL을 출력하고 실행 시간을 출력한다.
다음은 로그의 예시이다.
[START] * SQL SELECT /*+ INDEX_ASC (BASE "PROD_VSAM_KEY") */ SM_KEY, STYLE_NUMBER, YEAR, SIZE, SIZE_SCALE_PCT, EACH_PRICE_1, EACH_PRICE_2, EACH_PRICE_3, EACH_PRICE_4 FROM "PROD_VSAM" BASE WHERE ("SM_KEY", "STYLE_NUMBER", "YEAR", "SIZE") >= (:SM_KEY, :STYLE_NUMBER, :YEAR, :SIZE) AND ROWNUM = 1 ORDER BY "SM_KEY", "STYLE_NUMBER", "YEAR", "SIZE" ASC * KEY SM_KEY(50), STYLE_NUMBER(000100009), YEAR(22), SIZE() * Current Time : 2023-03-06 11:26:03 * Execution Time : 0.0020s [OPEN] * SQL SELECT /*+ INDEX_ASC (BASE "PROD_VSAM_KEY") */ SM_KEY, STYLE_NUMBER, YEAR, SIZE, SIZE_SCALE_PCT, EACH_PRICE_1, EACH_PRICE_2, EACH_PRICE_3, EACH_PRICE_4 FROM "PROD_VSAM" BASE WHERE ("SM_KEY", "STYLE_NUMBER", "YEAR", "SIZE") >= (:SM_KEY, :STYLE_NUMBER, :YEAR, :SIZE) ORDER BY "SM_KEY", "STYLE_NUMBER", "YEAR", "SIZE" ASC * KEY SM_KEY(50), STYLE_NUMBER(000100009), YEAR(22), SIZE(1X ) * Current Time : 2023-03-06 11:26:03 * Execution Time : 0.0441s
여기서 Execution Time이 큰 SQL을 대상으로 execution plan 등을 확인하고 튜닝 포인트를 찾는다.
2. 기타 성능 최적화 방법
추가로 시도해 볼 수 있는 성능 최적화 작업은 다음과 같다.
-
Copybook 필드 개수 줄이기
컬럼 개수가 많아질수록 SQL 처리 성능이 떨어지며 OpenFrame 엔진에도 부하가 생긴다. 따라서 필드를 합쳐서 컬럼의 개수를 줄이면 더 빠른 입출력이 가능하다.
-
Copybook 필드를 X로 만들기
Zoned decimal, packed decimal, integer 타입 필드의 경우 COBOL 규약에 맞는 데이터 포맷과 RDB에 저장되는 숫자 포맷이 다르기 때문에 입출력 과정에서 변환이 필요하다. 따라서 이런 필드가 많아질 경우 부하가 커진다.
반면 X 타입 필드는 데이터 변환 과정 없이 VARCHAR 컬럼에 그대로 저장되기 때문에 상대적으로 빠른 입출력이 가능하다.
위 두 경우를 조합해, copybook을 인덱스 키로 사용할 X 타입 필드 하나와 데이터의 나머지 부분에 대한 X 타입 필드 하나로 단순화하면 COBOL 프로그램의 입출력 성능을 크게 올릴 수 있다. 하지만 그만큼 SQL을 이용한 데이터 조작이 힘들어지는 단점도 있다.
-
PAGESIZE 옵션 활용하기
일부 사용자 프로그램의 경우 전체 레코드 개수는 많으나 READ 명령으로 한 번에 읽는 레코드 개수가 적어 READ 명령이 반복되는 경우가 있다. 이때 OpenFrame 엔진은 READ 명령이 반복되는 경우를 일반적인 것으로 판단해 READ 시점에 해당 키 이후에 나오는 모든 레코드를 가져오도록 쿼리하게 되는데, 이 쿼리는 레코드가 많을수록 느리기 때문에 상당히 비효율적으로 동작하게 된다.
이때 JCL의 DCB에 다음 예시와 같이 PAGESIZE=n 옵션을 주면 한 번에 가져올 레코드 개수를 지정할 수 있기 때문에 JOB에 따라 적절히 지정하여 실행 시간을 줄일 수 있다.
//JOB0 EXEC PGM=READTEST //DDONE DD DSN=TEST.VSAM,DISP=OLD, // DCB=(PAGESIZE=100) //SYSOUT DD SYSOUT=* //SYSPRINT DD SYSOUT=*