본문 바로가기

Note

[성능] 오라클 IFS 환경에서 varchar 문자열의 검색 키

업무적으로 IFS 를 구성해서 사용하는 경우는 Data Migration 인 경우다. 데이터 이관 작업으로 일회성으로 사용을 하기에 IFS 관련 문제가 될 경우는 없었다.

그러나 오라클 IFS 환경에서 개발을 지원하다 보니 성능 문제가 된 적이 있었다.

db2top 에서 세션 정보를 모니터링 하거나, 스냅샷 뷰인 sysibmadm.applications 의 appl_status 상태가 “Wait for Remote” 인 경우가 발생을 한다. nickname 데이터 조회 시, data source에서 sql 처리가 진행 중으로 결과를 기다리는 상태라고 해석해 볼 수 있겠다.

데이터가 많은 테이블이면 별 문제가 되지 않겠지만, 데이터 건수가 얼마 되지 않는데도 이런 식으로 “대기 상태”에 놓여 있다면 SQL을 살펴볼 필요가 있다. (예를 들어 select count(*) from 닉네임 수행 결과는 빠른데, select count(*) from 닉네임 where 컬럼=’문자열’ 이 느린 상황)

해당 문제는 db2expln을 통하여 sql plan을 확인하면서 원인이 찾아졌다.

원본 SQL

select * from 닉네임 where 컬럼 = ‘문자열’

DB2 옵티마이저가 작성한 SQL

select * from  닉네임 A0 where RPAD(A0.컬럼,길이,’ ‘)=RPAD(‘문자열’,길이,’ ‘)

 

문제는 SQL이 data source쪽(오라클)에서 실행될 때, 형 변환이 발생하여 Index Scan을 하지 못하게 되는 것 이였다.

이 문제는 “가변길이 문자열”에 대한 “공백’을 어떻게 처리하는 가의 문제로 귀결되는데, oracle은 “문자열” 과 “문자열 “을 다르게 인식하는 반면, DB2는 “문자열”과 “문자열 “을 같은 문자열로 인식을 한다.

“문자열의 끝의 공백”을 의미있게 볼 것인지 아닌지는 업무 상황에 따라 달라지겠지만, 개인적으로 “동일한 문자열”로 보는게 좋지 않을까? 생각을 한다. (일부터 뒤에 공백을 넣어 문자열을 관리하는 것은 낭비처럼 보이기도 하고, 그렇게 데이터를 정의하는 경우는 드물다고 생각한다.)

나와 같은 생각일까? DB2는 그래서 다른 DataSource의 가변 문자열은 명시적으로 “공백을 채워서” 값을 처리하도록 한 것 같다.

이런 상황에 놓이지 않도록 IFS 옵션에 “varchar_no_trailing_blanks” 옵션을 제공한다.

변수를 번역해 보자면 “varchar에 공백을 끌리지 않게 하는? 남기지 않는?” 정도가 되지 않을지..

이 옵션은 IFS 서버 구성 시 설정할 수 도 있고, nickname 의 컬럼에 지정할 수도 있다.

alter server 서버명 optims(add varchar_no_trailing_blanks ‘Y’)
alter nickname 닉네임 alter column 컬럼명 options (add varchar_no_trailing_blanks ‘Y’)

 

이후 db2expln 으로 수집된 optimizer 실행 계획은 다음과 같을 것이다.

select * from  닉네임 A0 where A0.컬럼 = ‘문자열’

 

IFS의 매커니즘에 대해서 깊게는 모르지만, 위와 같은 옵션에서 nickname 을 조회하는 SQL이 data source(ORACLE)에서도 실행되어진다는 것을 전제한다는 생각이 든다. 

데이터를 가지고 와서  DB2에서 처리되는 것이 아닌..  물론 IO부하로 원하는 값만 DB2로 넘어오게 하는 것이 올바른 처리 방식일 것이다.