(새 문서: {:튜닝 힌트 no merge}) |
편집 요약 없음 |
||
| 1번째 줄: | 1번째 줄: | ||
{:튜닝 힌트 no merge} | {{:튜닝 힌트 no merge}} | ||
2026년 1월 26일 (월) 11:06 기준 최신판
NO_MERGE 힌트
vpn_key NO_MERGE 힌트의 기본 개념
playlist_add_check- Oracle 옵티마이저는 기본적으로 뷰 병합(View Merging) 을 수행함.
- - 이는 인라인 뷰나 WITH 절의 쿼리를 메인 쿼리와 합쳐서 하나의 쿼리 블록으로 만드는 최적화 기법.
- - NO_MERGE 힌트는 인라인뷰 나 WITH절 쿼리를 메인쿼리와 합치지 말고 별개로 수행하라는 힌트임.
-- 병합 전 (논리적 구조) SELECT * FROM ( SELECT employee_id, salary FROM employees WHERE department_id = 10 ) v WHERE v.salary > 5000; -- 병합 후 (실제 실행) SELECT employee_id, salary FROM employees WHERE department_id = 10 AND salary > 5000;
NO_MERGE 힌트를 사용하는 주요 이유
조인 순서 및 방법 제어
- 뷰 병합이 일어나면 옵티마이저가 조인 순서를 재결정하는데, 이것이 비효율적일 수 있음.
SELECT /*+ NO_MERGE(v) */ d.department_name, v.avg_salary FROM departments d, (SELECT department_id, AVG(salary) avg_salary FROM employees GROUP BY department_id) v WHERE d.department_id = v.department_id;
- 뷰를 먼저 구체화(Materialization)하여 집계를 수행한 후 조인하는 것이 효율적인 경우가 많습니다.
중복 작업 방지
- 병합 시 같은 테이블을 여러 번 접근하게 되는 경우를 방지합니다.
SELECT /*+ NO_MERGE(v) */ v.*, t.additional_col FROM large_table t, (SELECT col1, col2, COMPLEX_FUNCTION(col3) as result FROM large_table WHERE expensive_condition = 'Y') v WHERE t.key = v.col1;
뷰를 병합하면 `COMPLEX_FUNCTION`이나 비용이 큰 조건이 중복 실행될 수 있습니다.
집계 후 필터링 강제
- 집계를 먼저 수행한 후 조건을 적용하고 싶을 때 사용.
SELECT /*+ NO_MERGE(summary) */ * FROM (SELECT department_id, COUNT(*) cnt, AVG(salary) avg_sal FROM employees GROUP BY department_id) summary WHERE summary.cnt > 10;
병합되면 `HAVING cnt > 10`으로 변환되어 실행 계획이 달라질 수 있습니다.
ROWNUM 처리 보존
- 뷰 내부의 ROWNUM 로직을 보존해야 할 때 필수적입니다.
SELECT /*+ NO_MERGE(top_n) */ e.employee_name, top_n.salary FROM employees e, (SELECT employee_id, salary FROM (SELECT employee_id, salary FROM employees ORDER BY salary DESC) WHERE ROWNUM <= 10) top_n WHERE e.employee_id = top_n.employee_id;
분석 함수 결과 활용
- 분석 함수(Window Function) 결과를 필터링 조건으로 사용할 때 필요.
SELECT /*+ NO_MERGE(ranked) */ * FROM (SELECT employee_id, salary, RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) rn FROM employees) ranked WHERE rn <= 3;
병렬 처리 최적화
- 뷰를 독립적으로 병렬 처리하고자 할 때 유용합니다.
SELECT /*+ NO_MERGE(v) PARALLEL(v, 4) */ * FROM (SELECT /*+ PARALLEL(e, 4) */ department_id, COUNT(*) cnt FROM huge_employees_table e GROUP BY department_id) v WHERE v.cnt > 100;
menu_book * 실행 계획 확인 방법
(중요) 실행 계획에서 `VIEW` 오퍼레이션이 보이면 뷰가 병합되지 않은 것입니다.
-- 병합 여부 확인 EXPLAIN PLAN FOR SELECT /*+ NO_MERGE(v) */ ... SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
- 주의사항
- NO_MERGE를 사용하면 뷰 구체화 비용이 추가됩니다 - 항상 실행 계획과 실제 수행 시간을 비교해야 합니다 - Oracle 버전에 따라 옵티마이저 동작이 다를 수 있습니다 - 통계 정보가 정확해야 올바른 판단이 가능합니다