KDUG를 방문했다가 oracle “connect by” 변환에 대한 질문이 있어 테스트를 해 보았다.
댓글 달기가 좀 불편한 점이 있어 recursive 처리에 대한 자세한 내용을 하지 못해서, 이곳에 좀 더 자세히 올리면 좋겠다 하는 생각에 적어 본다.
V9.1까지는 오라클 SQL 호환성 기능이 지원되지 않아 recursive 처리가 쉽지가 않았다. 9.5부터 connect by 사용이 가능해져서 전보다 변환 작업이 편해 졌을 것이라 생각한다.
참고로 오라클 SQL 호환성 기능을 활용하여 ORACLE 변환 작업한 기회가 많지 않아 어느 정도 가능한지 말하기는 어렵다. (단, 2년 전 V9.7 Cobra로 PoC 수행시 문제가 발생해서 connect by를 쓰지 않고 Common table로 변환 처리했던 기억이 어렴풋이 난다. ^^; )
테스트는 sample 데이터베이스의 department 테이블로 한다.
1. department 테이블 정의
$ db2 describe table department Column name schema Data type name Length Scale Nulls |
deptno 컬럼의 값과 admrdept 컬럼의 값이 동일하다. 이 2 컬럼을 통하여 “계층"(hierarchey) 처리가 가능하다.
2. department 데이터
$ db2 "select deptno, admrdept from department" DEPTNO ADMRDEPT 14 record(s) selected.. |
3. 계층 recurcive 처리
(1) deptno 컬럼과 admrdept 컬럼의 값이 동일한 값을 “최상위 계층”이라 정의하고 level에 0 값을 지정하여 parent 테이블에 저장한다. (아래 SQL의 붉은색 글씨)
(2) “최상위 계층”의 값의 deptno값과 department 테이블의 admrdept 값이 일치하는 값을 찾아
두번째 level의 데이터를 찾아 parent 테이블에 저장한다. (연두색 글씨)
(3) 두번째 level 값을 갖는 deptno 값을 통하여 department 테이블의 admrdept 값이 일치하는 값을 다시 찾아 세번째 level 데이터를 parent 테이블에 저장한다.
(4) 이렇게 parent 테이블에 저장된 데이터를 통하여 새로운 level의 데이터를 찾은 후, 전체 데이터에 대해 완료하면 parent 테이블을 조회하여 값은 반환시킨다.
(a.deptno != p.fkey 에 대한 이유는 글을 보시는 분들에게 숙제로 남겨 본다.)
$ db2 +p -tv << EOF > with parent (pkey, fkey, level) as PKEY LEVEL A00 0 14 record(s) selected with 1 warning messages printed. |
4. recursive가 되는 테이블의 SELECT 절에 recursive 처리는 넣어 처리하려면?
이것은 KDUG에 문의된 내용이다. 될까? 안될까? 궁금해서 테스트를 해 보았는데 한 SQL에서 recursive를 2번 사용하는 것은 지원되지 않는 듯 하다. (SQL0104N 에러 발생)
그래서 SELECT 절에서 사용되는 recursive 처리는 UDF (User define Function)으로 빼서 처리를 했더니 이중 recursive 처리가 되었다.
with parent (pkey, fkey, level) as select p.pkey,p.level,
실행 결과 SQL0104N An unexpected token "as" was found following "r (pkey,fkey, level)". Expected tokens may include: "JOIN". SQLSTATE=42601 |
SELECT 절의 recursive의 함수 처리
db2 +p -td"@" -v << EOF SQL0347W The recursive common table expression "INST97.SUBPAR" may contain an |
Recursive SQL
db2 +p -tv << EOF 실행 결과 PKEY LEVEL CNT A00 0 27 14 record(s) selected with 1 warning messages printed. |
Recursive 처리 구현이 어느 정도는 가능하지만, 데이터가 많은 경우 성능 저하는 심하게 발생할 수 밖에 없다. Connect by를 이용한 처리에 비해 부하가 더 심할지, 비슷한지는 비교해 본 적이 없기에 알 수 없지만 “꺼려지는 SQL” 이다.
'Note' 카테고리의 다른 글
[관리] DB2가 사용하는 메모리 확인은 어떻게? (0) | 2011.12.26 |
---|---|
[관리] 데이터베이스 크기 확인 (0) | 2011.12.26 |
[관리] 백업, 복구 히스토리, 아카이브 로그 자동 관리 (0) | 2011.12.12 |
[SQL] 익명 블록 (Anonymous Block) (0) | 2011.12.05 |
[SQL] 자율 트랜잭션(Autonomous Transaction) (0) | 2011.11.28 |