Oracle에서 MERGE 문은 INSERT와 UPDATE를 동시에 처리할 수 있어 많이 사용됩니다. 그러나 잘못 사용하면 성능 저하, 병목, 락 문제까지 발생할 수 있죠.
이 글에서는 Oracle MERGE 문을 더 빠르고 효율적으로 만들 수 있는 핵심 튜닝 전략 8가지를 실전 예제와 함께 소개합니다.
🔹 MERGE 문이란?
MERGE는 Oracle에서 UPSERT(UPDATE or INSERT)를 처리할 수 있는 SQL입니다. 단일 SQL로 데이터를 조건에 따라 존재하면 UPDATE, 없으면 INSERT하는 동작을 처리할 수 있습니다.
MERGE INTO target t
USING source s
ON (t.id = s.id)
WHEN MATCHED THEN
UPDATE SET t.name = s.name
WHEN NOT MATCHED THEN
INSERT (id, name) VALUES (s.id, s.name);하지만 데이터가 많아지고 조건이 복잡해지면, 이 문장은 성능 병목의 원인이 될 수 있습니다.
🔸 Oracle MERGE 성능 향상 팁 8가지
✅ 1. ON 조건에 인덱스 반드시 추가
MERGE는 ON 조건으로 두 테이블을 조인하므로, 해당 필드에 인덱스가 없다면 Full Table Scan이 발생합니다.
✅ 2. 변경된 값만 UPDATE (불필요한 UPDATE 방지)
WHEN MATCHED THEN
UPDATE SET t.col1 = s.col1
WHERE t.col1 IS DISTINCT FROM s.col1;✅ 3. USING 절 최소화: 서브쿼리 단순하게
USING 절에 복잡한 JOIN, GROUP BY, DISTINCT 사용하면 성능 저하의 주범이 됩니다.
✔️ 필요한 컬럼만 가져오고, 조건은 사전에 필터링하세요.
✅ 4. 병렬 처리 힌트 사용 (대량 데이터 시)
ALTER SESSION ENABLE PARALLEL DML;
MERGE /*+ parallel(t, 4) */ INTO target t
USING (SELECT /*+ parallel(s, 4) */ * FROM source s) s
ON (t.id = s.id) ...✅ 5. 실행 계획 확인: Full Scan 차단
EXPLAIN PLAN FOR
MERGE INTO ...
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);MERGE도 실행계획 분석으로 Index Scan 여부 확인 가능
✅ 6. 샤드 병목 방지: 대상 테이블에 파티셔닝 고려
파티션 테이블에 MERGE 시 Local Index, Partition Key와의 정렬이 중요
✅ 7. INSERT / UPDATE 분리도 고려
MERGE 문을 INSERT와 UPDATE로 나눴을 때 더 나은 성능이 나올 수도 있습니다
-- UPDATE 먼저 수행
UPDATE target t
SET ...
WHERE EXISTS (SELECT 1 FROM source s WHERE t.id = s.id);
-- INSERT는 나중에 수행
INSERT INTO target (...)
SELECT ...
FROM source s
WHERE NOT EXISTS (SELECT 1 FROM target t WHERE t.id = s.id);✅ 8. 최신 통계 수집
Oracle 옵티마이저가 잘못된 실행 계획을 선택하지 않도록 통계를 최신으로 유지하세요.
EXEC DBMS_STATS.GATHER_TABLE_STATS('SCHEMA_NAME', 'TABLE_NAME');🧠 마무리 요약
| 팁 | 요약 |
| 인덱스 | ON 조건에 인덱스 필수 |
| 변경 행만 UPDATE | 변경된 경우만 처리 |
| 병렬 처리 | 대량 데이터 시 병렬 힌트 적용 |
| 조건 최적화 | USING 서브쿼리 단순화 |
| 실행계획 분석 | Full Scan 여부 반드시 확인 |