우리 회사 데이터베이스를 티베로로 변경하기
과도한 하드 파싱(HARD PARSING) 0 0 79,370

by 티베로 티베로전환 티베로성능개선 [2018.09.30]


그림 4-4는 소속 회사의 전자공시 서비스의 펀드공시 검색 화면 펀드 검색 조건이 다. 사용자가 ‘펀드명’ 조건을 선택할 경우 우측의 텍스트 인풋 박스에는 펀드명 중 일부를 입력하게 되고 ‘펀드선택’ 조건을 선택할 경우는 펀드를 조회하는 다른 화 면을 제공하여 최종적으로는 펀드 코드를 입력받는다.

이 경우 사용자의 선택에 따 라 조건의 컬럼이 변경되므로 개발자는 바인드 변수를 사용하지 않고 참고 4-17 과 같이 사용자의 선택에 따라 서로 다른 컬럼을 사용자의 입력값과 함께 리터럴 (Literal)하게 구성하여 SQL을 결합하는 방식을 채택했다

이와 같은 구성은 개발 이 편리할지는 몰라도 리터럴하게 구성한 부분은 말 그대로 정해진 값이므로 리터 럴로 구성될 종류만큼 해당 SQL은 모두 다른 SQL로 DBMS는 인식하게 된다.

특 히 이 화면의 경우 사용자가 입력할 펀드명의 형식과 종류의 예측이 불가능할 만큼 다양한 종류의 입력값이 존재할 것이고 그 만큼 다양한 SQL이 존재할 것이므로 옵 티마이저가 새로운 SQL을 파싱하는 하드파싱에 의한 성능저하주5)가 발생을 했었다 (물론 최대한 소프트 파싱하려고 다양한 알고리즘이 티베로에 적용되어 있겠지만 일정 부분 하드파싱을 피할 수 없을 것이고 그것이 성능저하의 원인이 되었다).

| 주5 | ...(중략) 이렇게 최적으로 만들어진 SQL 플랜은 LIBRARY CACHE에 등록되어 같은 SQL에 대한 수행 요청 시 에 재활용되어 OPTIMIZER 단계를 건너뛰고 SQL을 수행하게 된다. 앞의 OPTIMIZER 단계를 거치는 PARSING 을 HARD PARSING이라 하고, OPTIMIZER 단계를 건너뛰고 LIBRARY CACHE에서 해당 플랜을 가져오는 PARSING을 SOFT PARSING이라고 부른다.
(출처 : Tibero Optimizer SQL Execution Plan, http://technet.tmaxsoft.com)

  • [그림 림 4-4] 조건의 동적 선택
  • 조건의 동적 선택

1) 리터럴하게 구현된 부분
if(입력클래스.사용자선택값() == null || 입력클래스.사용자선택값().equals("")) {
   //do nothing
 } else { 
	 if( 입력클래스.사용자선택조건().equals("펀드선택")) { 
	 
	   codeStr += " AND 상품정보테이블.상품코드 IN (" + 입력클래스.사용자선택값() + ")";
	 
	 } else if( 입력클래스.사용자선택조건().equals("펀드명")) {
	 
	  codeStr += " AND ( '" + 입력클래스.사용자선택값() + "' is null
	  or UPPER(REPLACE(TRIM(상품정보테이블.상품명),' ','')) LIKE '%'||
	  UPPER(REPLACE(TRIM( '" + 입력클래스.사용자선택값()() + "' ),' ','')) ||'%')";
	 }
 }
 whereSql = new String(기본str+비교Str + codeStr); 
 
 > 위 string은 각 조건에 따라 다음과 같은 SQL 형태로 결합된다. 
 따라서 사용자의 입력값에 따라 티베로에서 모드 
 다른 SQL로 인식하여 하드파싱할 가능성이 존재한다
 
 1-1) 펀드 선택의 경우
 : AND 상품정보테이블.상품코드 IN ('1234','5678','abcd','efgh')
 
 
 1-2) 펀드명의 경우
 : AND ( '입력값' IS NULL OR UPPER ( REPLACE (TRIM (상품정보테이블.상품명), 
   '', '')) LIKE '%' || UPPER ( REPLACE ( TRIM ( '입력값'), ' ', '')) || '%')

그렇다면 어떻게 해야 하드파싱의 부하를 피할 수 있을까? 많은 성능 관련 서적에서 강조하고 있듯이 바인드 변수를 사용하면 된다.

위와 같이 검색 조건이 다소 복 잡하여 바인드 변수를 사용할 방법이 없다고 판단되는 것도 조금만 생각을 해보면 가능하다. 소속 회사는 다음과 같이 해당 조건을 구성하여 원본 쿼리에 추가, 리터 럴 구성을 제거하여 문제를 해결할 수 있었다.

AND(
   (  :사용자선택조건 = '펀드명'
     and ( :사용자선택값 IS NULL 
          OR UPPER (REPLACE (TRIM(상품정보테이블.상품명), ' ', '')) LIKE '%'
          || UPPER (REPLACE (TRIM ( :사용자선택값), ' ', '')) || '%' ))
OR ( :사용자선택조건 = '펀드선택'
   and (:사용자선택값 IS NULL 
       OR INSTR(:사용자선택값, 상품정보테이블.상품코드_CD) >0))

  • - 해당 강좌는 도서 " [우리 회사 데이터베이스를 티베로로 변경하기]"의 내용을 옮겼습니다.
  • - 해당 도서는 기간계 DBMS(DATABASE MANAGEMENT SYSTEM)를 티베로로 전환하는 실제 프로젝트를 수행한 실무자가 DBMS 전환 과정과 실제 적용 사례, 문제 해결 과정 등을 자세하게 설명하고 있습니다.

- 강좌 URL : http://www.gurubee.net/lecture/4134

- 구루비 강좌는 개인의 학습용으로만 사용 할 수 있으며, 다른 웹 페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^

- 구루비 강좌는 서비스 제공을 위한 목적이나, 학원 홍보, 수익을 얻기 위한 용도로 사용 할 수 없습니다.

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