개요
MERGE는 소스 테이블과 타깃 테이블을 조인한 결과를 기준으로 삽입·갱신·삭제를 한 번에 처리하는 집합 기반 연산 여러 개의 개별 DML을 하나로 합쳐 실행 횟수와 스캔 비용을 줄이는 것이 목적 테이블 간 차이를 기준으로 동기화가 필요한 배치나 증분 적재 시 유용
핵심 개념
- 타깃 대상과 소스 입력의 조인 조건 정의
- WHEN MATCHED 조건에서 UPDATE 또는 DELETE 수행
- WHEN NOT MATCHED BY TARGET 조건에서 타깃에 INSERT 수행
- WHEN NOT MATCHED BY SOURCE 조건에서 소스에 없는 타깃 행을 DELETE 등으로 정리하는 패턴 지원
- 하나의 문장으로 트랜잭션 일관성 유지가 쉬움
기본 문법
필수 요소만 요약
MERGE INTO target AS t
USING source AS s
ON 조인_조건
WHEN MATCHED [AND 조건]
THEN UPDATE SET ... | DELETE
WHEN NOT MATCHED [BY TARGET] [AND 조건]
THEN INSERT (col, ...) VALUES (...)
WHEN NOT MATCHED BY SOURCE [AND 조건]
THEN DELETE
;세미콜론으로 문장을 종료해야 함 BY SOURCE 절을 사용하면 소스 기준으로 사라진 행 정리 가능
간단 예시
소스 MEMBER 기준으로 타깃 MEMBER_MEMO를 동기화하는 패턴
MERGE INTO MEMBER_MEMO AS MM
USING MEMBER AS M
ON MM.MemberIdx = M.MemberIdx
WHEN MATCHED THEN
UPDATE SET MM.MemberName = M.Name
WHEN NOT MATCHED THEN
INSERT (MemberName, Memo) VALUES (M.Name, N'후원 완료')
;필요 시 WHEN NOT MATCHED BY SOURCE THEN DELETE 를 추가해 소스에 없는 메모 행을 정리하는 풀 동기화 구성 가능
동작 원리와 성능 관점
- 조인 조건으로 매칭 집합 생성 후 조건절 평가 순서대로 액션 결정
- 하나의 집합 연산으로 I/O와 잠금 경합 감소 기대
- 단일 MERGE가 항상 빠른 것은 아님. 쿼리 계획, 인덱스, 조건 분기 수에 따라 개별 DML 대비 이득이 달라짐
- OUTPUT 절로 삽입·갱신·삭제된 행을 캡처해 감사나 후속 처리에 활용 가능
주의 사항
- 세미콜론 필수. 누락 시 구문 오류 발생 가능
- 조인 키는 유일 매칭 보장 필요. 한 타깃 행에 여러 소스가 매칭되면 오류 또는 예기치 않은 결과 유발
- WHEN 절이 여러 개인 경우 조건 충돌 방지. 더 구체적인 조건을 먼저 배치
- 트리거, 외래 키, 체크 제약 조건의 부수 효과 고려. 대량 작업 시 제약 검증 비용과 잠금 범위 증가 가능
- 인덱스 전략 중요. 조인 키와 필터 컬럼에 적절한 인덱스가 없으면 테이블 스캔 발생
- WHEN NOT MATCHED BY SOURCE는 삭제 성격. 잘못 쓰면 대량 삭제로 이어질 수 있어 범위를 조건으로 한정
- 동시성 환경에서는 조인 조건과 WHERE 조건의 일관성, Repeatable Read 이상 격리 또는 필요시 힌트 검토
- 롤백 비용이 큰 대량 MERGE는 배치 크기 분할, 트랜잭션 경계 제어, 임시 스테이징 테이블 사용 검토
베스트 프랙티스
- 소스는 스테이징 테이블로 고정하고 중복 제거 및 사전 집계 후 MERGE 수행
- 조인 키에 고카디널리티 인덱스 준비. 갱신 컬럼이 많은 경우 커버링 인덱스는 과하지 않게 설계
- 조건 분기 최소화. 필요 시 여러 MERGE 대신 명확한 두세 단계의 DML로 분리해 계획 단순화
- 변경 내역이 필요한 경우 OUTPUT으로 키와 액션 캡처 후 로깅 테이블에 적재
- 대량 삭제가 예상되면 BY SOURCE 삭제를 별도 배치로 분리하여 검증 절차 추가
마무리
MERGE는 테이블 간 동기화를 단순화하는 강력한 도구 조인 키의 유일성 보장, 조건 분기 설계, 인덱스 전략과 동시성까지 함께 점검하면 안전하고 예측 가능한 결과 확보 가능 필요 시 OUTPUT과 배치 분할을 결합해 감사와 성능을 함께 달성 가능