20220509

PostgreSQL 15 Merge 실전

PG 15 베타에 MERGE 구문이 들어왔다. 드디어. 그동안 INSERT ... ON CONFLICT DO UPDATE(upsert)로 대부분 해결했지만 조건 분기가 복잡해지면 지저분해졌음.

MERGE 구문 기본

MERGE INTO inventory AS t
USING stock_delta AS s
  ON t.sku = s.sku
WHEN MATCHED AND t.qty + s.delta = 0 THEN DELETE
WHEN MATCHED THEN UPDATE SET qty = t.qty + s.delta
WHEN NOT MATCHED THEN INSERT (sku, qty) VALUES (s.sku, s.delta);

하나의 statement로 INSERT/UPDATE/DELETE 분기. 표준 SQL이라 오라클/SQL Server 쓰던 사람이 익숙할 것.

upsert 대비 차이점

  • DELETE까지 가능
  • source가 subquery일 때 표현이 더 깔끔
  • 조건 분기가 여러 개일 때 가독성 좋음
  • 단, RETURNING이 MERGE에서는 아직 지원 안 됨. 이건 15 beta 기준.
    → upsert 써야 할 이유가 여전히 있음.

동시성

MERGE가 "concurrent-safe"하냐는 질문엔 조심해야 한다. MATCHED 판단과 INSERT 사이에 race가 존재할 수 있음. unique constraint 없이 MERGE만 믿으면 중복 insert 나올 수 있음. 여전히 PK/UNIQUE 제약 같이 써야 안전함.

공식 문서에도 "MERGE does not seek locks for the matched rows ... you should ensure appropriate isolation or constraints"류의 안내가 있다.

실사용

대량 CSV 동기화(외부에서 들어오는 재고 파일) 처리에 써봤는데 확실히 코드가 줄어듦. 기존에 5개 구문으로 나눠썼던 게 하나로 정리됨. 성능은 upsert 대비 큰 차이는 없었는데, 여러 분기의 경우 플랜이 좀 더 깔끔하게 나옴.

15는 아직 beta. 정식 릴리즈는 가을쯤. 지금부터 익히면 나중에 편하다.

댓글 없음: