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

# パーティションキーの選び方

> パーティションキーの選定方法を説明するページ

export const Image = ({img, alt, size = "lg"}) => {
  const normalizedSize = ["sm", "md", "lg"].includes(size) ? size : "lg";
  return <div className={`ch-image-${normalizedSize}`}>
      <Frame>
        <img src={img} alt={alt} />
      </Frame>
    </div>;
};

<Info>
  **データ管理のための手法**

  パーティション化は本質的にはデータ管理のための手法であり、クエリ最適化ツールではありません。特定のワークロードではパフォーマンス向上につながる場合もありますが、クエリを高速化するための第一の手段とすべきではありません。パーティションキーは、その影響を十分に理解したうえで慎重に選ぶ必要があり、データライフサイクルの要件や、明確に把握されたアクセスパターンに合致する場合にのみ適用すべきです。
</Info>

ClickHouse では、パーティション化によってデータが指定したキーに基づく論理セグメントに整理されます。これはテーブル作成時に `PARTITION BY` 句を使って定義し、一般に、時間インターバル、カテゴリ、その他の業務上重要な次元ごとに行をグループ化するために使用されます。パーティション化式の値が一意であるごとに、ディスク上にそれぞれ独立した物理パーティションが作成され、ClickHouse は各値に対応するデータを別々のパーツに保存します。パーティション化により、データ管理が改善され、保持ポリシーが簡素化されるほか、特定のクエリパターンで効果を発揮することがあります。

たとえば、パーティションキーとして `toStartOfMonth(date)` を使用する、次の UK price paid データセットテーブルを考えてみましょう。

```sql theme={null}
CREATE TABLE uk.uk_price_paid_simple_partitioned
(
  date Date,
  town LowCardinality(String),
  street LowCardinality(String),
  price UInt32
)
ENGINE = MergeTree
ORDER BY (town, street)
PARTITION BY toStartOfMonth(date)
```

行のセットがテーブルに挿入されるたびに、挿入されたすべての行を含む単一の データパーツ を (少なく[とも](/ja/reference/settings/session-settings#max_insert_block_size)) 1つ作成するのではなく ([こちら](/ja/concepts/core-concepts/parts)で説明しているとおり) 、ClickHouse は、挿入された行の一意なパーティションキーの値ごとに、新しい データパーツ を1つ作成します。

<Image img="https://mintcdn.com/private-7c7dfe99-postgresql-tls-support/KEXjaGd0XweSZg01/images/bestpractices/partitions.webp?fit=max&auto=format&n=KEXjaGd0XweSZg01&q=85&s=83e16d070ef0ec16e6c0ef1dbf2c9645" size="lg" alt="パーティション" width="3324" height="2270" data-path="images/bestpractices/partitions.webp" />

まず、ClickHouse server は、上の図に示した4行の挿入例の行を、パーティションキーの値 `toStartOfMonth(date)` ごとに分割します。次に、特定された各パーティションについて、行は通常どおり[処理されます](/ja/concepts/core-concepts/parts)。この処理では、いくつかの連続したステップ (① ソート、② カラムへの分割、③ 圧縮、④ ディスクへの書き込み) が実行されます。

パーティション化の詳細については、[このガイド](/ja/concepts/core-concepts/partitions)を参照することをおすすめします。

パーティション化を有効にすると、ClickHouse はパーティションをまたいでではなく、パーティション内でのみ データパーツ を[マージ](/ja/concepts/core-concepts/merges)します。これを上記の例のテーブルで示すと、次のようになります。

<Image img="https://mintcdn.com/private-7c7dfe99-postgresql-tls-support/KEXjaGd0XweSZg01/images/bestpractices/merges_with_partitions.webp?fit=max&auto=format&n=KEXjaGd0XweSZg01&q=85&s=d3fefda3f9787d8217355e36922b382d" size="md" alt="パーティション" width="2480" height="1870" data-path="images/bestpractices/merges_with_partitions.webp" />

<div id="applications-of-partitioning">
  ## パーティション化の用途
</div>

パーティション化は、ClickHouse で大規模なデータセットを管理するための強力な手法であり、特にオブザーバビリティや分析のユースケースで有効です。時間や業務ロジックに基づいて区切られることの多いパーティション全体を、単一のメタデータ操作で削除、移動、またはアーカイブできるため、データライフサイクルの運用を効率化できます。これは、行単位の削除やコピー操作よりも大幅に高速で、必要なリソースも少なくて済みます。また、パーティション化は有効期限 (TTL) や階層型ストレージといった ClickHouse の機能ともスムーズに連携するため、独自のオーケストレーションを用意しなくても、保持ポリシーやホット/コールドストレージ戦略を実装できます。たとえば、新しいデータは高速な SSD ベースのストレージに保持し、古いパーティションは自動的に低コストなオブジェクトストレージへ移動できます。

パーティション化は一部のワークロードではクエリパフォーマンスを改善できますが、応答時間に悪影響を与える場合もあります。

パーティションキーが主キーに含まれておらず、そのキーでフィルタする場合は、パーティション化によってクエリパフォーマンスが向上することがあります。例については、[こちら](/ja/concepts/core-concepts/partitions#query-optimization)を参照してください。

一方、クエリが複数のパーティションをまたぐ必要がある場合は、パーツの総数が増えることでパフォーマンスに悪影響が出ることがあります。このため、ユーザーはパーティション化をクエリ最適化の手法として検討する前に、自身のアクセスパターンを理解しておく必要があります。

要約すると、ユーザーはまずパーティション化をデータ管理の手法として捉えるべきです。データ管理の例については、オブザーバビリティのユースケースガイドにある["データ管理"](/ja/guides/use-cases/observability/build-your-own/managing-data)と、Core Concepts - Table partitions にある["テーブルパーティションは何のために使われますか？"](/ja/concepts/core-concepts/partitions#data-management)を参照してください。

<div id="choose-a-low-cardinality-partitioning-key">
  ## 低カーディナリティのパーティションキーを選択する
</div>

重要なのは、パーツ数が増えるほどクエリパフォーマンスに悪影響が出ることです。そのため ClickHouse では、パーツ数が [合計](/ja/reference/settings/merge-tree-settings#max_parts_in_total) または [パーティションごと](/ja/reference/settings/merge-tree-settings#parts_to_throw_insert) の指定された制限を超えると、insert に対して [「パーツが多すぎる」](/ja/resources/support-center/knowledge-base/troubleshooting/exception-too-many-parts) エラーが返されます。

パーティションキーに適切な **カーディナリティ** を選ぶことは非常に重要です。カーディナリティの高いパーティションキー、つまり異なるパーティション値の数が多いものは、データパーツの増加を招く可能性があります。ClickHouse はパーティションをまたいでパーツをマージしないため、パーティションが多すぎると未マージのパーツが増えすぎ、最終的に「パーツが多すぎる」エラーが発生します。[マージは不可欠です](/ja/concepts/core-concepts/merges)。ストレージの断片化を減らしてクエリ速度を最適化するうえで重要ですが、カーディナリティの高いパーティションでは、そのマージの余地が失われます。

一方、**低カーディナリティのパーティションキー**、つまり異なる値が 100 ～ 1,000 未満のものが、通常は最適です。これによりパーツマージを効率化でき、メタデータのオーバーヘッドを低く抑えられるほか、ストレージ内での過剰なオブジェクト作成も避けられます。さらに、ClickHouse はパーティションカラムに対して MinMax 索引 を自動的に構築するため、それらのカラムでフィルタするクエリを大幅に高速化できる場合があります。たとえば、テーブルが `toStartOfMonth(date)` でパーティション化されている場合、月でフィルタすると、エンジンは無関係なパーティションとそのパーツを完全にスキップできます。

パーティション化は一部のクエリパターンではパフォーマンス向上に役立つことがありますが、主な目的はデータ管理です。多くの場合、すべてのパーティションをまたぐクエリは、データの断片化が進み、スキャン対象のパーツも増えるため、パーティション化されていないテーブルより遅くなることがあります。パーティション化は慎重に使用し、選択するキーが必ず低カーディナリティで、かつデータライフサイクルポリシー (たとえば 有効期限 (TTL) による保持) に合っていることを常に確認してください。パーティション化が本当に必要か確信が持てない場合は、まずは使わずに始め、実際のアクセスパターンを見てから後で最適化するとよいでしょう。
