본문 바로가기

ETL Tools/Oracle Data Integrator

[ODI] Solution about Literal SQL error

** ODI Literal SQL error occurs.


Create date: 2012년 10월 23일

Created by Jeonghyeon Cheon


문제점

 ODI의 기본 ETL 로직 구현시 변수 사용은 기본적으로 '#' 문자를 prefix로 하여 구현 되는데, 

이렇게 되면 변수의 값이 상수값으로 치환되어 Query가 생성되며, 이에 따라 ETL 작업 수행시 Hard Parsing 이 발생하여 실행계획을 새로 생성하여 작업을 수행하게 된다. 

 이에 문제점이 발생하였는데, 원인과 해결책에 대하여 정리를 하려고 한다. 

 리터럴 sql 이 발생하는 원인은 배치 구간이 매우 짧은 ETL 작업의 경우, 같은 쿼리를 계속적으로 hard parsing 하게 되어, database의 쿼리 저장 풀을 차지하게 되어 리터럴 SQL이 발생하고, 최악의 경우, database가 다운되는 상황이 발생하였다. 


원인

이에 대하여 원인을 파악해 보니 원인은 3가지로, 

1. ODI가 자체적으로 발생시키는 Repostory 메타데이터 관련 Internal SQL


2. ODI로 개발된 ETL 배치 작업중, 배치 주기가 짧은 작업.


3. ODI 작업 로그를 남기기 위하여 관리될 때, 사용 하는 sessioini number 추출 적재 작업

으로 분류 할 수 있었고, 해당 원인에 대한 솔루션은 다음과 같다. 


해결방법

1. Internal SQL에 대한 이슈는 솔루션에서 제공하는 것이기 때문에, 해결할 수 없었으며, SR로 진행한 결과, 해당 이슈에 대한 패치가 나왔고 odi 11g 11.1.1.6.4 버전 패치를 적용함으로써 해당 문제는 해결할 수 있다. 


2. ODI로 개발시 변수사용은 #변수 만 있는 것이 아니다. :변수 방식으로 작업시 사용하면 바인드 변수로 사용되어, 같은 종류의 쿼리로 database에서 인식하기 때문에 하드파싱을 하지 않는 것으로 확인했다. 

리터럴 sql을 확인 할 수 있는 쿼리는 다음과 같다.


3. ODI 작업 로그를 수동으로 넣을때 sess_no를 사용하는데 이때는 <%=odiRef.getSession("SESS_NO")%>
처럼 사용하기 때문에 2번 해결책처럼 바인드 변수로 사용하는 것이 불가능하다. 하여, 이런 경우에는 Oracle stored Procedure를 생성하여 파라미터로 세션번호를 넘기는 방법으로 수행하여 로그를 적재하는 것으로 대체 한다.


위의 해결 방법은 단위 테스트되었으며, 적용 준비중입니다.