---
title: 매번 전체를 다시 안 긁는 법: 파이프라인 증분 적재 패턴
description: Lookup으로 마지막 워터마크를 읽고, Copy activity로 그 이후 데이터만 가져온 뒤 워터마크를 다시 갱신하는 Fabric 파이프라인 증분 적재 패턴을 단계별로 정리했어요.
date: 2026-09-26
  tags: [Data Pipeline, 증분 적재, 워터마크, Lookup, Fabric]
cards:
  - /cards/fabric-incremental-load-watermark-pattern/card-01.png
  - /cards/fabric-incremental-load-watermark-pattern/card-02.png
  - /cards/fabric-incremental-load-watermark-pattern/card-03.png
  - /cards/fabric-incremental-load-watermark-pattern/card-04.png
  - /cards/fabric-incremental-load-watermark-pattern/card-05.png
  - /cards/fabric-incremental-load-watermark-pattern/card-06.png
  - /cards/fabric-incremental-load-watermark-pattern/card-07.png
author: Lissa
source: https://interlinear.work/notes/fabric-incremental-load-watermark-pattern/
---

> **원문:** [Incrementally load data from Data Warehouse to Lakehouse](https://learn.microsoft.com/en-us/fabric/data-factory/tutorial-incremental-copy-data-warehouse-lakehouse)
> **게시일:** 2025-07-14 · **Microsoft Fabric 설명서**

Warehouse에서 Lakehouse로 데이터를 옮기는 파이프라인을 처음 만들 때 제일 쉬운 길은 "테이블 전체를 매번 다시 복사하기"예요. 행이 몇천 개일 땐 문제없죠. 그런데 원본이 수백만 행으로 커지면 이야기가 달라져요. 매 실행마다 안 바뀐 데이터까지 통째로 다시 긁으면 시간도, 컴퓨팅 비용도 그만큼 낭비돼요.

여기서 필요한 게 **증분 적재(incremental load)**예요. 지난번에 어디까지 가져왔는지를 기억해뒀다가, 그 이후에 새로 생기거나 바뀐 행만 가져오는 방식이죠. Fabric Data Factory 파이프라인은 이 패턴을 활동(activity) 네 개 조합만으로 구현할 수 있어요.

## 워터마크가 뭐예요?

**워터마크(watermark)<sup>1</sup>**는 "지난번 적재가 여기까지 끝났다"를 표시하는 값이에요. 보통 행이 추가되거나 수정될 때 같이 커지는 컬럼을 골라요. `LastModifytime` 같은 타임스탬프 컬럼이 대표적이고, 계속 증가하는 ID 컬럼도 쓸 수 있어요.

패턴의 핵심은 이거예요.

- 이 컬럼에서 **가장 큰 값**을 워터마크로 삼는다.
- 다음 실행에서는 "이전 워터마크보다 큰 행"만 가져온다.
- 가져오고 나면 워터마크 값을 갱신해서 다음 실행이 어디서부터 시작할지 알려준다.

그러려면 워터마크 값을 어딘가에 저장해둘 테이블이 하나 필요해요. Warehouse에 `watermarktable`처럼 `TableName`, `WatermarkValue` 두 컬럼짜리 작은 테이블을 만들고, 처음에는 아주 오래된 기준값(예: `1/1/2010`)을 넣어둬요. 이렇게 하면 첫 실행에서는 사실상 전체 데이터가 "워터마크 이후"로 잡혀서 통째로 들어오고, 그다음 실행부터 진짜 증분이 시작돼요.

## 활동 네 개로 조립하는 증분 패턴

파이프라인 캔버스에 다음 활동을 순서대로 놓고 연결해요.

**1. Lookup — 예전 워터마크 읽기**

Warehouse의 `watermarktable`을 조회해서 지난번에 저장해둔 워터마크 값을 가져와요. **Use query**를 **Table**로 두고 **First row only**를 켜면 값 하나만 딱 나와요.

**2. Lookup — 새 워터마크 계산하기**

이번엔 원본 테이블에다 직접 쿼리를 날려요.

```sql
select MAX(LastModifytime) as NewWatermarkvalue from data_source_table
```

지금 시점에서 원본 테이블이 가진 가장 최신 값을 "이번 실행이 끝나는 지점"으로 잡는 거예요.

**3. Copy activity — 그 사이 구간만 복사**

두 Lookup을 **On success**로 Copy activity에 연결하고, 소스 쿼리에서 두 워터마크 값을 경계로 걸어요.

```sql
select * from data_source_table
where LastModifytime > '@{activity('LookupOldWaterMarkActivity').output.firstRow.WatermarkValue}'
  and LastModifytime <= '@{activity('LookupNewWaterMarkActivity').output.firstRow.NewWatermarkvalue}'
```

`activity('활동이름').output.firstRow.컬럼명` 표현식<sup>2</sup>으로 앞 단계 Lookup 결과값을 그대로 끌어다 쓰는 거예요. 결과는 Lakehouse의 Files 아래에 새 파일로 떨어져요.

**4. Stored procedure activity — 워터마크 갱신**

마지막으로 Copy activity 성공 뒤에 저장 프로시저 활동을 붙여서, 방금 계산한 새 워터마크 값을 `watermarktable`에 다시 써넣어요. 파라미터로 `LastModifiedtime`(새 워터마크)과 `TableName`을 넘기면 되고, 저장 프로시저 안에서는 단순히 `UPDATE watermarktable SET WatermarkValue = ...` 한 줄이면 충분해요.

이 네 단계가 끝나면 다음 파이프라인 실행은 자동으로 이번에 갱신된 값부터 다시 시작해요. 사람이 어디까지 됐는지 기억할 필요가 없어요.

## 실제로 돌려보면 어떻게 보이나요

처음 실행하면 워터마크가 아주 오래된 기본값이라, 원본 테이블 전체가 새 파일로 복사돼요. 이후 원본에 새 행 두어 개를 더 넣고 파이프라인을 다시 돌리면, 이번엔 그 새 행만 담긴 새 파일이 Lakehouse에 하나 더 생겨요. 매번 파일 전체를 새로 쓰는 게 아니라 "이번 실행분"만 별도 파일로 쌓이는 구조라서, 언제 어떤 데이터가 들어왔는지 파일 단위로 추적하기도 쉬워져요.

## 다른 테이블에도 그대로 쓰려면

이 패턴을 테이블마다 하나씩 손으로 파이프라인을 만들어 반복하기보다, 워터마크 테이블에 테이블 이름별로 행을 여러 개 두고 파이프라인을 파라미터화하면 여러 테이블을 같은 로직으로 순회할 수 있어요. 테이블이 몇 개 안 되면 지금 소개한 네 단계 구조를 그대로 복제하는 것만으로도 충분히 실용적이에요.

## 정리

증분 적재의 핵심은 **워터마크 컬럼 하나를 정하고, 그 값을 어딘가에 기억해두는 것**뿐이에요. Fabric 파이프라인에서는 Lookup 두 개(예전 값·새 값), Copy activity(그 사이 구간만 복사), Stored procedure(값 갱신) 네 활동만 연결하면 이 패턴이 완성돼요. 테이블이 커질수록, 그리고 파이프라인을 자주 돌릴수록 이 차이가 비용과 실행 시간에 그대로 드러나요.

---

## 어휘 주석

1. **워터마크(watermark):** 데이터 적재 작업이 "여기까지 처리했다"고 표시해두는 기준값. 보통 타임스탬프나 계속 증가하는 ID 컬럼의 최댓값을 사용해요.
2. **활동 참조 표현식(`activity().output`):** 파이프라인의 한 활동이 낸 결과값을 뒤에 오는 다른 활동에서 그대로 가져다 쓰는 동적 콘텐츠 문법. 앞 단계 Lookup의 조회 결과를 다음 Copy activity의 조건절에 바로 꽂아 넣을 때 이런 식으로 씁니다.