금백조의 개발 블로그

[MSSQL][SQLP]MERGE문을 사용하여 INSERT, UPDATE 한번에 처리(DML 튜닝) 본문

Database/SQL Server(MSSQL)

[MSSQL][SQLP]MERGE문을 사용하여 INSERT, UPDATE 한번에 처리(DML 튜닝)

금백조 2021. 4. 21. 23:58
반응형

서론

 

요즘 SQLP 취득을 위하여 SQL 전문가 가이드 2013 Edition 책을 읽고 있습니다. 읽은 내용 중 DML 튜닝 내용에서 각각의 INSERT, UPDATE DML문을 MERGE문으로 변환하여 One SQL로 효율적으로 처리할 수 있는 내용을 알게 되었습니다. 그래서 오늘은 MERGE문에 대해서 정리해보겠습니다.

 


 

본론

 

[구문 형식]

 

MERGE INTO [타겟테이블] AS [테이블명칭1]
USING [매핑테이블] AS [테이블명칭2] ON (매핑키 조건문)
WHEN MATCHED THEN 
UPDATE SET ...
WHEN NOT MATCHED THEN
INSERT (...) VALUES (...);

 

 

[장점]

 

1.하나의 SQL로 작성할 수 있어 효율적입니다.

2. 쿼리문을 좀 더 간결하게 작성할 수 있습니다.

 

[주의사항]

 

1.MERGE문 끝에는 ;(세미콜론)이 존재해야 합니다.

2.MS 공식문서(하단 참조)에 의하면 행 필터 조건을 ON절에 명시할 경우 예상과는 다른 수행 결과가 발생할 수 있습니다. 따라서 필터 조건이 필요할 경우 Inline View 안의 WHERE문에 조건을 추가해야 합니다.

 

[활용]

 

BI(Business Intelligence), DW(Data Warehouse)에서 사용하는 읽기전용 테이블에 갱신할 데이터를 INSERT, UPDATE 할 시 유용하게 사용할 수 있습니다.

 

예제

 

[테스트 테이블 T1, T2 생성]

 

CREATE TABLE T1 (
	 KEY_COL NVARCHAR(8) PRIMARY KEY
	,NUM_COL INT
)

CREATE TABLE T2 (
	 KEY_COL NVARCHAR(8) PRIMARY KEY
	,NUM_COL INT
)

 

[테스트 데이터 생성]

 

DECLARE @MAX INT = 1000
DECLARE @NUM INT = 0

WHILE @NUM<@MAX
BEGIN
	INSERT INTO T1(KEY_COL,NUM_COL) VALUES (CONVERT(NVARCHAR,@NUM)+'A',@NUM)
	SET @NUM+=1
END

SET @MAX = 500
SET @NUM = 0

WHILE @NUM<@MAX
BEGIN
	INSERT INTO T2(KEY_COL,NUM_COL) VALUES (CONVERT(NVARCHAR,@NUM)+'A',500-@NUM)
	SET @NUM+=1
END

SELECT * FROM T1
SELECT * FROM T2

 

[각각의 INSERT, UPDATE DML]

 

--일반 DML 문
UPDATE A
SET A.NUM_COL = B.NUM_COL
FROM T2 A
INNER JOIN T1 B ON A.KEY_COL = B.KEY_COL

INSERT INTO T2
SELECT T1.KEY_COL, T1.NUM_COL FROM T1
OUTER APPLY (SELECT TOP 1 T1.NUM_COL FROM T2 WHERE T1.KEY_COL = T2.KEY_COL) A
WHERE A.NUM_COL IS NULL

 

 

 

[MERGE 문을 통한 INSERT, UPDATE]

 

--MERGE 문
MERGE INTO T2 A
USING T1 B ON A.KEY_COL = B.KEY_COL
WHEN MATCHED THEN--T1, T2에 매칭되는 행이 존재할 경우 
UPDATE SET A.NUM_COL = B.NUM_COL--T1.NUM_COL값을 T2.NUM_COL에 UPDATE
WHEN NOT MATCHED THEN--T2에는 없고 T1에만 존재하는 행일 경우
INSERT (KEY_COL, NUM_COL) VALUES (B.KEY_COL, B.NUM_COL);--T1행을 T2에 ISNERT

 

[실행계획 비교]

 

[각각의 INSERT, UPDATE DML 실행계획]

 

[MERGE 문 실행계획]

 

 

설명 : 각각의 INSERT, UPDATE DML은 INSERT, UPDATE를 각각 따로 처리하므로 2개의 실행계획이 발생합니다. 반면에 MERGE문은 ISNERT, UPDATE를 한번에 처리하여 1개의 실행계획이 발생합니다. 따라서 인덱스 스캔 횟수도 줄어들게 되므로 INSERT, UPDATE를 각각 따로 처리하는 것보다 일반적으로 효율적이라 볼 수 있습니다.

 

 


 

결론

 

위의 정리한 내용을 참고하여 향후 프로젝트에서도 MERGE문을 사용할 기회가 생기면 적극적으로 활용해봐야겠습니다. 

 

Reference

 

1.[MERGE(Transact-SQL)]

docs.microsoft.com/ko-kr/sql/t-sql/statements/merge-transact-sql?view=sql-server-ver15

 

MERGE(Transact-SQL) - SQL Server

MERGE(Transact-SQL)

docs.microsoft.com

2. [SQL 전문가 가이드 2013 Edition]

[고급 SQL 튜닝] - [제3절 DML 튜닝] - [p714 ~ p715]

반응형