> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-mintlify-8c05c8a2.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> 경량 업데이트는 패치 파트를 사용해 데이터베이스의 데이터를 업데이트하는 과정을 더 간편하게 만듭니다.

# 경량 UPDATE SQL 문

export const galaxyOnClick = eventName => () => {
  try {
    if (typeof window !== "undefined" && window.galaxy && eventName) {
      window.galaxy.track(eventName, {
        interaction: "click"
      });
    }
  } catch (e) {}
};

export const BetaBadge = ({link, galaxyTrack, galaxyEvent}) => {
  if (link) {
    return <a href={link} target="_blank" rel="noopener noreferrer" className="betaBadge" onClick={galaxyTrack && galaxyEvent ? galaxyOnClick(galaxyEvent) : undefined}>
                <Icon />
                <span>베타</span>
            </a>;
  }
  return <div className="betaBadge">
            <Icon />
            <span>
                베타 기능. 
                <u>
                    <a href="/docs/beta-and-experimental-features#beta-features">
                        자세히 보기.
                    </a>
                </u>
            </span>
        </div>;
};

<Note>
  경량 업데이트는 현재 베타입니다.
  문제가 발생하면 [ClickHouse 리포지토리](https://github.com/clickhouse/clickhouse/issues)에 이슈를 등록해 주십시오.
</Note>

경량 `UPDATE` SQL 문은 표현식 `filter_expr`에 일치하는 `[db.]table` 테이블의 행을 업데이트합니다.
이는 데이터 파트에서 전체 컬럼을 재작성하는 비용이 큰 [`ALTER TABLE ... UPDATE`](/ko/reference/statements/alter/update) 쿼리와 구분하기 위해 "경량 업데이트"라고 부릅니다.
이 기능은 [`MergeTree`](/ko/reference/engines/table-engines/mergetree-family/mergetree) 테이블 엔진 계열에서만 사용할 수 있습니다.

```sql theme={null}
UPDATE [db.]table [ON CLUSTER cluster] SET column1 = expr1 [, ...] [IN PARTITION partition_expr] WHERE filter_expr;
```

`filter_expr`는 `UInt8` 유형이어야 합니다. 이 쿼리는 `filter_expr`의 값이 0이 아닌 행에서, 지정된 컬럼의 값을 해당 표현식에 대응하는 값으로 업데이트합니다.
값은 `CAST` 연산자를 사용해 컬럼 유형으로 변환됩니다. 프라이머리 키 또는 파티션 키 계산에 사용되는 컬럼은 업데이트할 수 없습니다.

<div id="examples">
  ## 예시
</div>

```sql theme={null}
UPDATE hits SET Title = 'Updated Title' WHERE EventDate = today();

UPDATE wikistat SET hits = hits + 1, time = now() WHERE path = 'ClickHouse';
```

<div id="lightweight-update-does-not-update-data-immediately">
  ## 경량 업데이트는 데이터를 즉시 업데이트하지 않습니다
</div>

경량 `UPDATE`는 \*\*패치 파트(patch parts)\*\*를 사용해 구현됩니다. 패치 파트는 업데이트된 컬럼과 행만 포함하는 특별한 유형의 데이터 파트(data part)입니다.
경량 `UPDATE`는 패치 파트를 생성하지만, 저장소에 있는 원본 데이터를 물리적으로 즉시 수정하지는 않습니다.
업데이트 과정은 `INSERT ... SELECT ...` 쿼리와 비슷하지만, `UPDATE` 쿼리는 패치 파트 생성이 완료될 때까지 기다린 뒤에 반환됩니다.

업데이트된 값의 특징은 다음과 같습니다.

* 패치가 적용되므로 `SELECT` 쿼리에서 **즉시 확인할 수 있습니다**
* 이후 머지 및 뮤테이션 과정에서만 **물리적으로 구체화됩니다**
* 모든 활성 파트에 패치가 구체화되면 **자동으로 정리됩니다**

<div id="lightweight-update-requirements">
  ## 경량 업데이트 요구 사항
</div>

경량 업데이트는 [`MergeTree`](/ko/reference/engines/table-engines/mergetree-family/mergetree), [`ReplacingMergeTree`](/ko/reference/engines/table-engines/mergetree-family/replacingmergetree), [`CollapsingMergeTree`](/ko/reference/engines/table-engines/mergetree-family/collapsingmergetree), [`VersionedCollapsingMergeTree`](/ko/reference/engines/table-engines/mergetree-family/versionedcollapsingmergetree) 엔진과 그 [`Replicated`](/ko/reference/engines/table-engines/mergetree-family/replication) 및 [`Shared`](/ko/products/cloud/features/infrastructure/shared-merge-tree) 버전에서 지원됩니다.

경량 업데이트를 사용하려면 테이블 설정 [`enable_block_number_column`](/ko/reference/settings/merge-tree-settings#enable_block_number_column) 및 [`enable_block_offset_column`](/ko/reference/settings/merge-tree-settings#enable_block_offset_column)을 사용하여 `_block_number` 및 `_block_offset` 컬럼의 머티리얼라이즈를 활성화해야 합니다.

<div id="lightweight-delete">
  ## 경량 DELETE
</div>

[경량 `DELETE`](/ko/snippets/delete) 쿼리는 `ALTER UPDATE` mutation 대신 경량 `UPDATE`로 실행할 수 있습니다. 경량 `DELETE`의 동작 방식은 [`lightweight_delete_mode`](/ko/reference/settings/session-settings#lightweight_delete_mode) 설정으로 제어됩니다.

<div id="performance-considerations">
  ## 성능 고려 사항
</div>

**경량 업데이트의 장점:**

* 업데이트의 지연 시간은 `INSERT ... SELECT ...` 쿼리의 지연 시간과 비슷합니다
* 데이터 파트(data part)의 전체 컬럼이 아니라 업데이트된 컬럼과 값만 기록됩니다
* 현재 실행 중인 머지/뮤테이션이 완료될 때까지 기다릴 필요가 없으므로 업데이트의 지연 시간을 예측할 수 있습니다
* 경량 업데이트는 병렬로 실행할 수 있습니다

**잠재적인 성능 영향:**

* 패치를 적용해야 하는 `SELECT` 쿼리에는 오버헤드가 추가됩니다
* 패치를 적용해야 하는 데이터 파트의 컬럼에는 [스키핑 인덱스](/ko/reference/engines/table-engines/mergetree-family/mergetree#table_engine-mergetree-data_skipping-indexes)가 사용되지 않습니다. 테이블에 패치 파트가 있으면 패치를 적용할 필요가 없는 데이터 파트를 포함해 [프로젝션](/ko/reference/engines/table-engines/mergetree-family/mergetree#projections)도 사용되지 않습니다.
* 지나치게 빈번한 소규모 업데이트는 "too many parts" 오류를 유발할 수 있습니다. 예를 들어 업데이트할 id를 `WHERE` 절의 단일 `IN` 절에 넣는 방식으로 여러 업데이트를 하나의 쿼리로 묶는 것이 좋습니다
* 경량 업데이트는 소량의 행(테이블의 약 10%까지)을 업데이트하도록 설계되었습니다. 더 많은 양을 업데이트해야 한다면 [`ALTER TABLE ... UPDATE`](/ko/reference/statements/alter/update) 뮤테이션을 사용하는 것이 좋습니다

<div id="concurrent-operations">
  ## 동시 작업
</div>

경량 업데이트는 일반적인 뮤테이션과 달리 현재 실행 중인 머지나 뮤테이션이 완료될 때까지 기다리지 않습니다.
동시에 실행되는 경량 업데이트의 일관성은 설정 [`update_sequential_consistency`](/ko/reference/settings/session-settings#update_sequential_consistency) 및 [`update_parallel_mode`](/ko/reference/settings/session-settings#update_parallel_mode)로 제어됩니다.

<div id="update-permissions">
  ## `UPDATE` 권한
</div>

`UPDATE`를 사용하려면 `ALTER UPDATE` 권한이 필요합니다. 특정 사용자가 지정된 테이블에서 `UPDATE` SQL 문을 실행할 수 있도록 하려면 다음을 실행하세요:

```sql theme={null}
GRANT ALTER UPDATE ON db.table TO username;
```

<div id="details-of-the-implementation">
  ## 구현 세부 사항
</div>

패치 파트는 일반 파트와 동일하지만, 업데이트된 컬럼과 몇 가지 시스템 컬럼만 포함합니다.

* `_part` - 원본 파트의 이름
* `_part_offset` - 원본 파트에서의 행 번호
* `_block_number` - 원본 파트에서 해당 행의 block 번호
* `_block_offset` - 원본 파트에서 해당 행의 block 오프셋
* `_data_version` - 업데이트된 데이터의 데이터 버전(`UPDATE` 쿼리에 할당된 block 번호)

평균적으로 패치 파트에서는 업데이트된 각 행마다 약 40바이트(비압축 데이터)의 오버헤드가 발생합니다.
시스템 컬럼은 업데이트해야 할 원본 파트의 행을 찾는 데 도움이 됩니다.
시스템 컬럼은 원본 파트의 [가상 컬럼](/ko/reference/engines/table-engines/mergetree-family/mergetree#virtual-columns)과 연관되어 있으며, 패치 파트를 적용해야 할 경우 읽기 시 추가됩니다.
패치 파트는 `_part`와 `_part_offset`을 기준으로 정렬됩니다.

패치 파트는 원본 파트와 서로 다른 파티션에 속합니다.
패치 파트의 파티션 ID는 `patch-<hash of column names in patch part>-<original_partition_id>`입니다.
따라서 컬럼이 서로 다른 패치 파트는 서로 다른 파티션에 저장됩니다.
예를 들어 세 가지 업데이트 `SET x = 1 WHERE <cond>`, `SET y = 1 WHERE <cond>`, `SET x = 1, y = 1 WHERE <cond>`는 서로 다른 3개의 파티션에 3개의 패치 파트를 생성합니다.

패치 파트는 서로 머지될 수 있으며, 이를 통해 `SELECT` 쿼리에서 적용해야 하는 패치 수를 줄이고 오버헤드를 낮출 수 있습니다. 패치 파트 머지에는 `_data_version`을 버전 컬럼으로 사용하는 [replacing](/ko/reference/engines/table-engines/mergetree-family/replacingmergetree) 머지 알고리즘이 사용됩니다.
따라서 패치 파트에는 각 업데이트된 행에 대한 최신 버전만 항상 저장됩니다.

경량 업데이트는 현재 실행 중인 머지와 뮤테이션이 완료되기를 기다리지 않으며, 항상 데이터 파트의 현재 스냅샷을 사용해 업데이트를 실행하고 패치 파트를 생성합니다.
따라서 패치 파트를 적용하는 경우는 두 가지가 있을 수 있습니다.

예를 들어 파트 `A`를 읽을 때 패치 파트 `X`를 적용해야 한다고 가정하겠습니다.

* `X`에 파트 `A` 자체가 포함된 경우. 이는 `UPDATE`가 실행될 때 `A`가 머지에 참여하고 있지 않았던 경우에 발생합니다.
* `X`에 파트 `A`에 포함된 `B`와 `C`가 포함된 경우. 이는 `UPDATE`가 실행될 때 (`B`, `C`) -> `A` 머지가 진행 중이었던 경우에 발생합니다.

이 두 가지 경우에 대해 패치 파트를 적용하는 방식도 각각 두 가지가 있습니다.

* 정렬된 컬럼 `_part`, `_part_offset`을 기준으로 머지를 사용합니다.
* `_block_number`, `_block_offset` 컬럼을 기준으로 join을 사용합니다.

join 모드는 merge 모드보다 느리고 더 많은 메모리가 필요하지만, 사용 빈도는 더 낮습니다.

<div id="related-content">
  ## 관련 콘텐츠
</div>

* [`ALTER UPDATE`](/ko/reference/statements/alter/update) - 부하가 큰 `UPDATE` 작업
* [Lightweight `DELETE`](/ko/snippets/delete) - 경량 `DELETE` 작업
* [`APPLY PATCHES`](/ko/reference/statements/alter/apply-patches) - 패치를 데이터 파트에 물리적으로 머티리얼라이즈하도록 강제하는 mutation 작업
