[SQL Server] Bulk UpSert

소소한 팁일 수 있는데 모르는 분은 저처럼 모르셨을 것 같아 공유합니다.
이번 주 1100만 건 정도 들어 있는 Table에 Column 3개를 추가하는 역정규화 작업을 진행했었습니다.
DB에 대한 이해가 없었기 때문에 자연스럽게

  1. 콘솔앱을 만들고
  2. 콘솔앱에서 필요한 데이터를 모두 가져온 뒤
  3. 콘솔앱에서 데이터를 만들어서
  4. 역정규화 테이블로 반복문을 통해 update

이렇게 했었는데요. 아시는 분들은 아시겠지만 위 프로세스는 엄청나게 오래걸립니다. 관련해서 서칭을 해보니, UPDATE or MERGE of very big tables in SQL Server - Stack Overflow 이런 링크를 찾았습니다. 이 포스트를 보니, 3억 개의 데이터가 있는 테이블을 40분정도면 업데이트 한다고 하는데 이것보다 더 빠른 수행속도를 원하는 글 입니다. 아래 이런저런 설명이 달려있지만 질문자가 MERGE 문을 통해 대규모 업데이트를 수행했다는 사실을 파악할 수 있었습니다. 다른 커뮤니티 지인들도 MERGE JOIN, Update JOIN을 알아보라고 추천해주셨었습니다.

위 글 덕분에 MERGE 쿼리를 작성했고, 1100만 건의 데이터에 대해 update를 4분 30초만에 수행 했습니다. 제 환경은 아래와 같습니다.

  • varchar(15)
  • nvarchar(50)
  • varchar(30)
  • nvarchar(50)
  • int
  • decimal(7,2)
  • nvarchar(100)
  • nvarchar(500)
  • int
  • decimal(15, 3)
  • tinyint
  • char(2)
  • datetime2
  • nvarchar(10)

테이블에 대해

4 Core, 3.40 GHz, 16GB RAM, SQL Server 2016 의 스펙으로 진행했습니다.
대규모 업데이트에 대해서 노하우가 전혀 없으신 분들께 추천드립니다.

5개의 좋아요

merge 쿼리를 활용해 데이터를 UPDATE 하셨다는 말씀이신거죠?
key값 +@ 의 조건을 통해 switch문처럼 활용하는 방법도 있었던 걸로 기억이 나네요.

아니면, merge문에 join구문을 섞었다는 말씀이실까요?
제가 맥락을 잘 이해 하지 못한 듯 합니다 @_@

2개의 좋아요

제가 기존에 Merge 문을 잘 모를 떄는 1건에 대해서만 처리했었습니다. 아래와 같은 식입니다.

MERGE table1 AS A
USING
(
     SELECT @수정데이터1 AS 수정데이터
) AS B
ON
(
     A.수정데이터 = B.수정데이터
)
WHEN MATCHED THEN
    UPDATE SET
        수정데이터 = B.수정데이터;

요런 식이었다면,

MERGE table1 AS A
USING
(
     SELECT *
     FROM table2
) AS B
ON
(
     A.수정데이터 = B.수정데이터
)
WHEN MATCHED THEN
    UPDATE SET
        수정데이터 = B.수정데이터;

이렇게 Source가 되는 부분을 테이블로 바꿨다는 뜻입니다.
쿼리를 잘 몰라서 생기는 문제였습니다.

2개의 좋아요

아하…
여러 행으로 쓸 수 있는 기능이라
익숙해지면 엄청 편한 기능이라고 생각합니다 :smiley:

이 부분 때문에 헷갈렷던 것 같네요 ^^;

2개의 좋아요

MERGE 방식으로 이미 되어버려서 더 이상 찾지는 않았지만 Update Join은 아마 아래의 글을 말하는 것 같습니다.

merge join은 source 부분에 join 쿼리를 넣은 source라는 말인 것 같습니다…ㅎㅎ

2개의 좋아요