13번째 줄: | 13번째 줄: | ||
|+ 계층쿼리(connect by 절) 튜닝 포인트 | |+ 계층쿼리(connect by 절) 튜닝 포인트 | ||
|- | |- | ||
! | ! 튜닝포인트 !! 설명 | ||
|- | |- | ||
| 인덱스 활용 || CONNECT BY에 사용되는 컬럼 (empno, mgr)에 인덱스 생성 | | 인덱스 활용 || CONNECT BY에 사용되는 컬럼 (empno, mgr)에 인덱스 생성 |
2025년 4월 7일 (월) 17:12 기준 최신판
계층쿼리 예시
SELECT empno, ename, mgr FROM emp START WITH mgr IS NULL CONNECT BY PRIOR empno = mgr;
계층쿼리(connect by 절) 튜닝 포인트
튜닝포인트 | 설명 |
---|---|
인덱스 활용 | CONNECT BY에 사용되는 컬럼 (empno, mgr)에 인덱스 생성 |
CONNECT_BY_ISCYCLE 사용 | 사이클(루프) 방지를 통해 무한루프 방지 |
NOCYCLE 옵션 사용 | CONNECT BY NOCYCLE PRIOR ... → 무한 루프 방지 |
WHERE 절 위치 | CONNECT BY 안에 넣을 조건 vs WHERE 절에 둘 조건 구분 |
LEVEL 컬럼 활용 | 쿼리 깊이를 제한 (WHERE LEVEL <= 5) 하여 성능 확보 |
병렬처리 제한 | 계층 쿼리는 병렬 실행이 제한적이므로 주의 필요 |
MATERIALIZE 힌트 | 중첩 서브쿼리 사용 시 /*+ MATERIALIZE */ 힌트 고려 |
항목 설명
인덱스 생성 필수
CREATE INDEX idx_emp_mgr ON emp(mgr); CREATE INDEX idx_emp_empno ON emp(empno);
NOCYCLE & CONNECT_BY_ISCYCLE
SELECT empno, ename, mgr, CONNECT_BY_ISCYCLE FROM emp START WITH mgr IS NULL CONNECT BY NOCYCLE PRIOR empno = mgr;
level 로 깊이 제한
WHERE LEVEL <= 5
where 절의 조건의 위치
- 불필요한 조건을 WHERE에 두면 Oracle이 먼저 전체 트리를 생성한 후 필터링함.
- 가능하면 CONNECT BY 절 내에 조건을 넣는 것이 효율적.
예제
CREATE TABLE org_tree ( emp_id NUMBER PRIMARY KEY, emp_name VARCHAR2(50), mgr_id NUMBER ); INSERT INTO org_tree VALUES (1, 'CEO', NULL); INSERT INTO org_tree VALUES (2, 'VP1', 1); INSERT INTO org_tree VALUES (3, 'VP2', 1); INSERT INTO org_tree VALUES (4, 'Manager1', 2); INSERT INTO org_tree VALUES (5, 'Manager2', 2); INSERT INTO org_tree VALUES (6, 'Staff1', 4); INSERT INTO org_tree VALUES (7, 'Staff2', 4); COMMIT;
SELECT LEVEL, emp_id, emp_name, mgr_id FROM org_tree START WITH mgr_id IS NULL CONNECT BY PRIOR emp_id = mgr_id;
CREATE INDEX idx_org_tree_mgr_id ON org_tree(mgr_id);
- 이 인덱스는 CONNECT BY PRIOR emp_id = mgr_id 조건에서 자식에서 부모로 탐색할 때 사용됨.
EXPLAIN PLAN FOR SELECT LEVEL, emp_id, emp_name, mgr_id FROM org_tree START WITH mgr_id IS NULL CONNECT BY PRIOR emp_id = mgr_id; SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
---------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Cost (%CPU)| ---------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | 5 (100)| | 1 | CONNECT BY WITH FILTERING | | | | | 2 | TABLE ACCESS FULL | ORG_TREE | 1 | 2 0% | | 3 | NESTED LOOPS | | | | | 4 | CONNECT BY PUMP | | | | | 5 | TABLE ACCESS BY INDEX ROWID| ORG_TREE | 1 | 2 0% | | 6 | INDEX RANGE SCAN | IDX_ORG_TREE_MGR | 1 | 1 0% | ----------------------------------------------------------------------------------