2. 컴퓨터 이야기/프로그래밍

connect by ~ start with ~ order siblings by ~ 문에 대한 Oracle 9i Plan (실행계획) 2

래빗 크리스 2009. 8. 16. 16:30

이번에 설명하는 것은 ACL 을 사용자별로 다루지 않고 그룹단위로 다루는 경우를 설명한다.
이보다 더 나은 방법도 얼마든지 많을테지만..

먼저 실행계획부터.. (눈이 마구 돌아가져.. ㅋㅋ)
아래 그림을 보면 딱 눈에 보이시죠..?
Filter 와 Hash Join, Count 등에 Nested Loops (Cost=471 Card=23 Bytes=3K) 가 동일하게 사용되었습니다.
그 안쪽에 있는 Nested Loops (Cost=2 Card=23 Bytes=1K) 는 테이블을 악세스 하지 않고 Index 에서만 돕니다.


이제 쿼리를 함 보겠습니다.
위에서 설명했던 첫번째 Netsted Loop 에 해당하는 것이 (select seq_category ~ group by seq_category) 입니다.
group by 를 하는 이유는, 한 사람이 여러 ACL 그룹에 속하는 경우 해당 카테고리도 여러개가 나오기 때문입니다.
resno 는 Resident No 로 User 마다 고유하게 부여된 번호입니다.
seq_acl_group 은 그룹별 ACl 고유번호 입니다.
out_yn 은 사외에서의 접속을 허용할때 Y, 사내에서만 접속할때 N 입니다.
만약 사외 IP 에서 메뉴에 접속을 하면 'Y' 값을 넣으면 되겠죠. 물론, 사내에서라면 b.out_yn 조건을 빼면 됩니다.


이미 아시는 바와 같이 start with 부터 DB 가 작업을 시작합니다.
Alias a 테이블과 Alias b 테이블을 참조하여 모든 대상을 가져오는데,
Alias a 테이블은 기술된 힌트 /*+ index .. */ 를 이용합니다.
옵티마이저가 Alias a 보다는 Alias b 를 외측루프로 하는 것이 낫겠다 싶은가 봅니다.
물론, Alias b 에 기술된 쿼리는 resno 를 기준으로 하기 때문에 카테고리 전체보다 범위가 적겠지요.
인덱스도 없고 힌트도 없다면 아무래도 Full Scan 이 되니까, 이 부분은 적당하게 조정해 주세요.

connect by 는 트리구조의 루트를 어떤 것으로 할 것이냐를 체크하는 것이니까 넘어가구요.
단지 prior 가 기술되는 쪽이 상수로 취급되고, prior 가 등호 앞에 있든 뒤에 있든 상관이 없습니다..
start with 문과 비슷한 조건으로 connect by 에 기술하면 됩니다.

start with 와 connect by 에 의해 외측루프에 주욱 담고 내측루프와 조인한 다음에는
order by siblings by 에 기술된 대로 결과셋을 담아서 최종 결과를 리턴합니다.

where 조건은 조인 용도가 아니라 결과 체크용이랍니다.
여기서 사용된 open_yn 은 해당 카테고리에 대한 표시를 허용할 것이냐를 구분짓습니다.
만약 접근권한이 설정되어 있어도 해당 카테고리를 표시 불허로 하면 트리구조에 표시되지 않겠죠.
menu_yn 은 메뉴로 사용되는 카테고리인지 컨텐츠로 사용되는 카테고리인지를 체크해 줍니다.
컨텐츠에 해당하는 카테고리는 메뉴 트리구조에서 제외됩니다.

트리 구조의 카테고리는 여기까지 설명하면 이해가 될 듯합니다.
이상입니다.