메뉴 여닫기
개인 메뉴 토글
로그인하지 않음
만약 지금 편집한다면 당신의 IP 주소가 공개될 수 있습니다.
3번째 줄: 3번째 줄:
::::{{핵심
::::{{핵심
|제목= NO_MERGE 힌트의 기본 개념
|제목= NO_MERGE 힌트의 기본 개념
|내용= # Oracle 옵티마이저는 기본적으로 뷰 병합(View Merging) 을 수행함.  
|내용= - Oracle 옵티마이저는 기본적으로 뷰 병합(View Merging) 을 수행함.  
# 이는 인라인 뷰나 WITH 절의 쿼리를 메인 쿼리와 합쳐서 하나의 쿼리 블록으로 만드는 최적화 기법.
- 이는 인라인 뷰나 WITH 절의 쿼리를 메인 쿼리와 합쳐서 하나의 쿼리 블록으로 만드는 최적화 기법.
}}
}}
::<source lang=sql>
::<source lang=sql>

2026년 1월 26일 (월) 11:11 판

NO_MERGE 힌트

  vpn_key NO_MERGE 힌트의 기본 개념

  playlist_add_check- Oracle 옵티마이저는 기본적으로 뷰 병합(View Merging) 을 수행함.

- 이는 인라인 뷰나 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;


      1. 6. **병렬 처리 최적화**

뷰를 독립적으로 병렬 처리하고자 할 때 유용합니다.

```sql 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; ```

    1. 실행 계획 확인 방법

```sql -- 병합 여부 확인 EXPLAIN PLAN FOR SELECT /*+ NO_MERGE(v) */ ...

SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY); ```

실행 계획에서 `VIEW` 오퍼레이션이 보이면 뷰가 병합되지 않은 것입니다.

    1. 주의사항

- NO_MERGE를 사용하면 뷰 구체화 비용이 추가됩니다 - 항상 실행 계획과 실제 수행 시간을 비교해야 합니다 - Oracle 버전에 따라 옵티마이저 동작이 다를 수 있습니다 - 통계 정보가 정확해야 올바른 판단이 가능합니다

DBA로서 튜닝 작업 시 특정 케이스에 대해 더 자세한 설명이 필요하시면 말씀해주세요!