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

> 論理更新により、パッチパートを使用したデータベース内のデータ更新が簡単になります。

# 論理更新 UPDATE ステートメント

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>Beta</span>
            </a>;
  }
  return <div className="betaBadge">
            <Icon />
            <span>
                Beta feature. 
                <u>
                    <a href="/docs/beta-and-experimental-features#beta-features">
                        Learn more.
                    </a>
                </u>
            </span>
        </div>;
};

<Note>
  論理更新は現在ベータです。
  問題が発生した場合は、[ClickHouseリポジトリ](https://github.com/clickhouse/clickhouse/issues) に issue を登録してください。
</Note>

論理更新 `UPDATE` ステートメントは、式 `filter_expr` に一致するテーブル `[db.]table` の行を更新します。
これは、データパーツ内のカラム全体を書き換える重量級の処理である [`ALTER TABLE ... UPDATE`](/ja/reference/statements/alter/update) クエリと対比して、"lightweight update" と呼ばれています。
この機能は、[`MergeTree`](/ja/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` が非ゼロ値となる行について、指定したカラムの値を、それぞれ対応する式の値に更新します。
値は `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` は、**パッチパート** (更新されたカラムと行のみを含む特殊なデータパート) を使用して実装されています。
論理更新 `UPDATE` ではパッチパートが作成されますが、ストレージ内の元データが直ちに物理的に変更されるわけではありません。
更新処理は `INSERT ... SELECT ...` クエリに似ていますが、`UPDATE` クエリはパッチパートの作成が完了するまで待機してから結果を返します。

更新後の値は次のとおりです。

* パッチの適用により、`SELECT` クエリから**即座に参照可能**
* **物理的に実体化**されるのは、後続のマージやミューテーションの実行時のみ
* アクティブなすべてのパーツでパッチが実体化されると、**自動的にクリーンアップ**される

<div id="lightweight-update-requirements">
  ## 論理更新の要件
</div>

論理更新は、[`MergeTree`](/ja/reference/engines/table-engines/mergetree-family/mergetree)、[`ReplacingMergeTree`](/ja/reference/engines/table-engines/mergetree-family/replacingmergetree)、[`CollapsingMergeTree`](/ja/reference/engines/table-engines/mergetree-family/collapsingmergetree)、[`VersionedCollapsingMergeTree`](/ja/reference/engines/table-engines/mergetree-family/versionedcollapsingmergetree) エンジンと、それらの [`Replicated`](/ja/reference/engines/table-engines/mergetree-family/replication) および [`Shared`](/ja/products/cloud/features/infrastructure/shared-merge-tree) バージョンでサポートされています。

論理更新を使用するには、テーブル設定 [`enable_block_number_column`](/ja/reference/settings/merge-tree-settings#enable_block_number_column) と [`enable_block_offset_column`](/ja/reference/settings/merge-tree-settings#enable_block_offset_column) を使用して、`_block_number` および `_block_offset` カラムのマテリアライズを有効にする必要があります。

<div id="lightweight-delete">
  ## 論理削除
</div>

[論理削除 `DELETE`](/ja/reference/statements/delete) クエリは、`ALTER UPDATE` ミューテーションではなく、論理更新 `UPDATE` として実行できます。論理削除 `DELETE` の実装は、[`lightweight_delete_mode`](/ja/reference/settings/session-settings#lightweight_delete_mode) 設定によって制御されます。

<div id="performance-considerations">
  ## パフォーマンスに関する考慮事項
</div>

**論理更新の利点:**

* 更新のレイテンシは、`INSERT ... SELECT ...` クエリのレイテンシと同程度です
* 書き込まれるのは更新されたカラムと値のみであり、データパーツ内のカラム全体は書き換えられません
* 現在実行中のマージやミューテーションの完了を待つ必要がないため、更新のレイテンシは予測しやすくなります
* 論理更新は並列に実行できます

**想定されるパフォーマンスへの影響:**

* パッチを適用する必要がある `SELECT` クエリにはオーバーヘッドが発生します
* パッチを適用する必要があるデータパーツ内のカラムでは、[スキッピング索引](/ja/reference/engines/table-engines/mergetree-family/mergetree#table_engine-mergetree-data_skipping-indexes) は使用されません。[プロジェクション](/ja/reference/engines/table-engines/mergetree-family/mergetree#projections) は、パッチを適用する必要がないデータパーツを含め、テーブルにパッチパートが存在する場合は使用されません。
* 頻繁すぎる小規模な更新は、"パーツが多すぎる" エラーを引き起こす可能性があります。複数の更新を 1 つのクエリにまとめることを推奨します。たとえば、更新対象の id を 1 つの `IN` 句にまとめて `WHERE` 句で指定します
* 論理更新は、少量の行 (テーブルの約 10% まで) を更新するように設計されています。より多くの行を更新する必要がある場合は、[`ALTER TABLE ... UPDATE`](/ja/reference/statements/alter/update) ミューテーションを使用することを推奨します

<div id="concurrent-operations">
  ## 同時実行操作
</div>

論理更新は、重い ミューテーション とは異なり、現在実行中の マージ や ミューテーション の完了を待ちません。
同時実行される論理更新の整合性は、設定 [`update_sequential_consistency`](/ja/reference/settings/session-settings#update_sequential_consistency) と [`update_parallel_mode`](/ja/reference/settings/session-settings#update_parallel_mode) によって制御されます。

<div id="update-permissions">
  ## `UPDATE` の権限
</div>

`UPDATE` には `ALTER UPDATE` 権限が必要です。特定のテーブルで特定のユーザーに `UPDATE` ステートメントを許可するには、次を実行します。

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

<div id="details-of-the-implementation">
  ## 実装の詳細
</div>

パッチパートは通常のパーツと同じですが、更新されたカラムと、いくつかのシステムカラムのみを含みます。

* `_part` - 元のパーツ名
* `_part_offset` - 元のパーツ内の行番号
* `_block_number` - 元のパーツ内におけるその行のブロック番号
* `_block_offset` - 元のパーツ内におけるその行のブロックオフセット
* `_data_version` - 更新データのデータバージョン (`UPDATE` クエリに割り当てられたブロック番号)

平均すると、パッチパートでは更新された1行あたり約40バイトのオーバーヘッド (非圧縮データ) が発生します。
システムカラムは、更新対象となる元のパーツ内の行を特定するのに役立ちます。
システムカラムは元のパーツ内の [仮想カラム](/ja/reference/engines/table-engines/mergetree-family/mergetree#virtual-columns) に対応しており、パッチパートを適用する必要がある場合は、読み取り時に追加されます。
パッチパートは `_part` と `_part_offset` でソートされます。

パッチパートは、元のパーツとは異なるパーティションに属します。
パッチパートのパーティションIDは `patch-<hash of column names in patch part>-<original_partition_id>` です。
そのため、含まれるカラムが異なるパッチパートは別々のパーティションに格納されます。
たとえば、3つの更新 `SET x = 1 WHERE <cond>`, `SET y = 1 WHERE <cond>` および `SET x = 1, y = 1 WHERE <cond>` によって、3つの異なるパーティションに3つのパッチパートが作成されます。

パッチパート同士をマージすることで、`SELECT` クエリで適用されるパッチの数を減らし、オーバーヘッドを削減できます。パッチパートのマージでは、`_data_version` をバージョンカラムとして [replacing](/ja/reference/engines/table-engines/mergetree-family/replacingmergetree) マージアルゴリズムを使用します。
そのため、パッチパートには常に、そのパーツ内で更新された各行の最新バージョンが保持されます。

論理更新は、現在実行中のマージやミューテーションの完了を待たず、常にデータパーツの現在のスナップショットを使用して更新を実行し、パッチパートを生成します。
そのため、パッチパートの適用には2つのケースがあります。

たとえば、パーツ `A` を読み取る際にパッチパート `X` を適用する必要があるとします。

* `X` にパーツ `A` 自体が含まれている場合。これは、`UPDATE` の実行時に `A` がマージに参加していなかった場合に起こります。
* `X` にパーツ `B` と `C` が含まれており、それらがパーツ `A` にカバーされている場合。これは、`UPDATE` の実行時にマージ (`B`, `C`) -> `A` が進行中だった場合に起こります。

この2つのケースに対して、パッチパートの適用方法もそれぞれ2通りあります。

* ソート済みカラム `_part`, `_part_offset` を使ったマージを使用する。
* `_block_number`, `_block_offset` カラムを使った join を使用する。

join モードはマージモードより低速で、より多くのメモリを必要としますが、使用頻度は低めです。

<div id="related-content">
  ## 関連コンテンツ
</div>

* [`ALTER UPDATE`](/ja/reference/statements/alter/update) - 負荷の高い `UPDATE` 操作
* [論理削除 `DELETE`](/ja/reference/statements/delete) - 論理削除 `DELETE` 操作
* [`APPLY PATCHES`](/ja/reference/statements/alter/apply-patches) - パッチをデータパーツに物理的に実体化する (ミューテーション 操作)
