🔑 Oracle MERGE 성능 개선 방안
- ON 조건 인덱스 최적화 – MERGE는 대상과 소스를 조인하므로 ON 조건 컬럼에 인덱스 필요
- 변경된 값만 UPDATE – 불필요한 UPDATE 방지
- USING 절 단순화 – 복잡한 JOIN, GROUP BY 최소화
- 병렬 처리 힌트 – 대용량 배치 작업 시 효과적
- 실행 계획 확인 – EXPLAIN PLAN으로 Full Scan 여부 점검
- 파티셔닝 활용 – 병목 완화 및 Local Index 사용
- MERGE 분리 전략 – UPDATE와 INSERT를 분리해 옵티마이저 활용 극대화
- 최신 통계 유지 – DBMS_STATS로 실행 계획 정확성 확보
⚠️ 실무에서 자주 발생하는 문제
- Snapshot too old 오류 – Undo 영역 과다 사용 → 사전 필터링으로 해결
- 인덱스 무시 문제 – 조건을 인라인 뷰로 먼저 적용
- 뷰 패턴 주의 – DISTINCT, GROUP BY 포함된 뷰는 업데이트 불가
📊 개선 방법 비교
| 개선 방법 | 효과 | 적용 상황 |
|---|---|---|
| ON 조건 인덱스 | Full Scan 방지 | 모든 MERGE |
| 변경된 값만 UPDATE | Undo/Redo 감소 | 대량 UPDATE |
| USING 절 단순화 | 실행 계획 단순화 | 복잡한 소스 쿼리 |
| 병렬 처리 힌트 | 대용량 처리 속도 향상 | 배치 작업 |
| MERGE 분리 전략 | 옵티마이저 활용 극대화 | 대규모 UPSERT |
| 최신 통계 유지 | 실행 계획 정확성 확보 | 정기적 유지보수 |
📌 MERGE 실행 계획 튜닝 예제
1. 기본 MERGE 구문
MERGE INTO target t
USING source s
ON (t.id = s.id)
WHEN MATCHED THEN
UPDATE SET t.value = s.value
WHEN NOT MATCHED THEN
INSERT (id, value) VALUES (s.id, s.value);
2. 실행 계획 (인덱스 없는 경우)
| Id | Operation | Name | Rows | Cost |
| 2 | TABLE ACCESS FULL | TARGET | 100K | 500 |
| 3 | TABLE ACCESS FULL | SOURCE | 100K | 400 |
3. 실행 계획 (인덱스 추가 후)
| Id | Operation | Name | Rows | Cost |
| 2 | TABLE ACCESS BY INDEX ROWID | TARGET | 100K | 120 |
| 3 | INDEX RANGE SCAN | IDX_TARGET_ID | 100K | 80 |
| 4 | TABLE ACCESS BY INDEX ROWID | SOURCE | 100K | 100 |
| 5 | INDEX RANGE SCAN | IDX_SOURCE_ID | 100K | 70 |
📌 병렬 MERGE 예제
ALTER SESSION ENABLE PARALLEL DML;
MERGE /*+ parallel(t 4) parallel(s 4) */
INTO target t
USING source s
ON (t.id = s.id)
WHEN MATCHED THEN
UPDATE SET t.value = s.value
WHEN NOT MATCHED THEN
INSERT (id, value) VALUES (s.id, s.value);
병렬 실행 계획 특징
| Id | Operation | Name |
| 1 | PX COORDINATOR | |
| 3 | PX SEND BROADCAST | |
| 5 | PX BLOCK ITERATOR | SOURCE |
| 9 | PX BLOCK ITERATOR | TARGET |
👉 PX 단계가 나타나면 병렬 처리 성공! 대용량 MERGE 성능이 크게 향상됩니다.


