편집 요약 없음 |
|||
| (같은 사용자의 중간 판 4개는 보이지 않습니다) | |||
| 57번째 줄: | 57번째 줄: | ||
::* 집계를 먼저 수행한 후 조건을 적용하고 싶을 때 사용. | ::* 집계를 먼저 수행한 후 조건을 적용하고 싶을 때 사용. | ||
::<source lang=sql> | ::::<source lang=sql> | ||
SELECT /*+ NO_MERGE(summary) */ | SELECT /*+ NO_MERGE(summary) */ | ||
* | * | ||
| 70번째 줄: | 70번째 줄: | ||
==== ROWNUM 처리 보존 ==== | ==== ROWNUM 처리 보존 ==== | ||
::* 뷰 내부의 ROWNUM 로직을 보존해야 할 때 필수적입니다. | ::* 뷰 내부의 ROWNUM 로직을 보존해야 할 때 필수적입니다. | ||
::<source lang=sql> | ::::<source lang=sql> | ||
SELECT /*+ NO_MERGE(top_n) */ | SELECT /*+ NO_MERGE(top_n) */ | ||
e.employee_name, top_n.salary | e.employee_name, top_n.salary | ||
| 87번째 줄: | 87번째 줄: | ||
::* 분석 함수(Window Function) 결과를 필터링 조건으로 사용할 때 필요. | ::* 분석 함수(Window Function) 결과를 필터링 조건으로 사용할 때 필요. | ||
::<source lang=sql> | ::::<source lang=sql> | ||
SELECT /*+ NO_MERGE(ranked) */ | SELECT /*+ NO_MERGE(ranked) */ | ||
* | * | ||
| 98번째 줄: | 98번째 줄: | ||
=== 병렬 처리 최적화 === | === 병렬 처리 최적화 === | ||
뷰를 독립적으로 병렬 처리하고자 할 때 유용합니다. | ::* 뷰를 독립적으로 병렬 처리하고자 할 때 유용합니다. | ||
::<source lang=sql> | ::::<source lang=sql> | ||
SELECT /*+ NO_MERGE(v) PARALLEL(v, 4) */ | SELECT /*+ NO_MERGE(v) PARALLEL(v, 4) */ | ||
* | * | ||
| 110번째 줄: | 110번째 줄: | ||
</source> | </source> | ||
{{요점 | |||
|배경색 = #f7d4063e | |||
|선굵기 = 3px | |||
|테두리색 = #de5a5a | |||
|사이즈 = 100% | |||
|둥굴기 = 4px | |||
|스타일 = dashed | |||
|내용 ='''* 실행 계획 확인 방법''' | |||
<source lang=sql> | |||
-- 병합 여부 확인 | -- 병합 여부 확인 | ||
EXPLAIN PLAN FOR | EXPLAIN PLAN FOR | ||
| 120번째 줄: | 128번째 줄: | ||
</source> | </source> | ||
'''(중요) 실행 계획에서 `VIEW` 오퍼레이션이 보이면 뷰가 병합되지 않은 것입니다.''' | <center>'''(중요) 실행 계획에서 `VIEW` 오퍼레이션이 보이면 뷰가 병합되지 않은 것입니다.'''</center> | ||
}} | |||
* 주의사항 | |||
- NO_MERGE를 사용하면 뷰 구체화 비용이 추가됩니다 | - NO_MERGE를 사용하면 뷰 구체화 비용이 추가됩니다 | ||
| 128번째 줄: | 137번째 줄: | ||
- Oracle 버전에 따라 옵티마이저 동작이 다를 수 있습니다 | - Oracle 버전에 따라 옵티마이저 동작이 다를 수 있습니다 | ||
- 통계 정보가 정확해야 올바른 판단이 가능합니다 | - 통계 정보가 정확해야 올바른 판단이 가능합니다 | ||
[[category:oracle]] | [[category:oracle]] | ||
2026년 1월 26일 (월) 11:34 기준 최신판
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 버전에 따라 옵티마이저 동작이 다를 수 있습니다 - 통계 정보가 정확해야 올바른 판단이 가능합니다