すべてのプロダクト
Search
ドキュメントセンター

AnalyticDB:テーブルのディストリビューションの定義

最終更新日:Mar 28, 2026

AnalyticDB for PostgreSQL では、テーブル作成時に選択したディストリビューション方式に基づき、テーブルデータをコンピュートノード間で分散します。選択する方式および分散キーは、クラスター全体におけるクエリパフォーマンス、データのバランス、結合効率に直接影響します。

ディストリビューション方式

AnalyticDB for PostgreSQL では、以下の 3 種類のディストリビューション方式をサポートしています。

CREATE TABLE <table_name> (...)
[ DISTRIBUTED BY (<column> [,..] ) | DISTRIBUTED RANDOMLY | DISTRIBUTED REPLICATED ]
説明

V4.3 ではハッシュディストリビューションとランダムディストリビューションのみをサポートしています。レプリケーテッドディストリビューションは V6.0 で導入されました。

方式構文動作の仕組み使用タイミング
ハッシュディストリビューション(デフォルト)DISTRIBUTED BY (column, [...])各行を分散列のハッシュ値に基づいてコンピュートノードに割り当てます。同じハッシュ値を持つ行は同一ノードに配置されます。DISTRIBUTED 句が指定されていない場合、テーブルはプライマリキーを分散キーとして使用します。適切なキーが存在しない場合は、ランダムディストリビューションにフォールバックします。ほとんどのテーブルに使用します。分散キーを用いたクエリでは、コロケーテッド結合およびコンピュートノードのフィルタリングが可能になります。
ランダムディストリビューションDISTRIBUTED RANDOMLYラウンドロビンアルゴリズムを用いて、各行をすべてのコンピュートノードに均等に分散します。同じハッシュ値を持つ行が異なるノードに配置される可能性があります。ハッシュディストリビューションに適した列が存在しない場合にのみ使用します。コロケーテッド結合およびコンピュートノードのフィルタリングはサポートされません。
レプリケーテッドディストリビューションDISTRIBUTED REPLICATEDテーブルの完全なコピーをすべてのコンピュートノードに格納します。頻繁に大規模テーブルと結合される小規模なルックアップテーブルに使用します。結合パフォーマンスを向上させます。

例:

-- ハッシュディストリビューション
CREATE TABLE products (
    name        varchar(40),
    prod_id     integer,
    supplier_id integer
) DISTRIBUTED BY (prod_id);

-- ランダムディストリビューション
CREATE TABLE random_stuff (
    things  text,
    doodads text,
    etc     text
) DISTRIBUTED RANDOMLY;

-- レプリケーテッドディストリビューション
CREATE TABLE replicated_stuff (
    things  text,
    doodads text,
    etc     text
) DISTRIBUTED REPLICATED;

ハッシュディストリビューションがクエリルーティングに与える影響

クエリが分散キーでフィルター処理を行う場合、AnalyticDB for PostgreSQL は該当する行を保持するコンピュートノードのみにクエリをルーティングします。たとえば、以下のクエリは prod_id = 101 を含むノードにのみ送信され、すべてのノードをスキャンすることはありません。

SELECT * FROM products WHERE prod_id = 101;

分散キーの選択

ハッシュディストリビューション向けに効果的な分散キーを選択するには、以下の手順に従ってください。

ステップ 1:データが均等に分散される列を選択します。

データの不均等な分散は「データスキュー」を引き起こし、一部のコンピュートノードに他のノードよりも大幅に多くの行が集中して負荷が増加し、クエリ実行が遅くなる原因となります。カーディナリティが低く、スキューを生じやすいブール値、時刻、日付などの列は避けてください。

ステップ 2:結合条件で頻繁に使用される列を選択します。

結合キーと分散キーが一致する場合、AnalyticDB for PostgreSQL は コロケーテッド結合を実行します。この場合、各コンピュートノードは自身のローカルデータのみを結合し、ノード間でのデータ移動は発生しません。

結合キーと分散キーが異なる場合、クエリエンジンは結合前に リディストリビューションモーションまたは ブロードキャストモーションを実行する必要があります。いずれもコロケーテッド結合に比べてネットワークオーバーヘッドが大きくなります。

Collocated joinRedistributed joinBroadcast join

ステップ 3:クエリフィルターとして頻繁に使用される列を選択します。

分散キーでフィルター処理を行うと、AnalyticDB for PostgreSQL は関連する行を保持しないコンピュートノードをスキップできるため、クエリごとのスキャン対象データ量を削減できます。

ステップ 4:一意キーを優先します。

プライマリキーなど一意キーはカーディナリティを最大化し、行をノード間で均等に分散させることが保証されます。テーブルにプライマリキーが定義されている場合は、それを起点として検討してください。

ステップ 5:複合分散キーを検討します。

単一の列で上記の要件を満たさない場合、2 つ以上の列を組み合わせて分散キーとします。

CREATE TABLE t1 (c1 int, c2 int) DISTRIBUTED BY (c1, c2);

分散キーの使用制限

  • 分散キーの列は更新できません。 分散の再割り当てを行うには、ALTER TABLE ... SET DISTRIBUTED BY を使用してください。

  • 分散キーは、プライマリキーまたは一意キーの一部である必要があります。 以下の例では、分散キー c2 がプライマリキー c1 に含まれていないため、実行に失敗します。

    CREATE TABLE t1 (c1 int, c2 int, PRIMARY KEY (c1)) DISTRIBUTED BY (c2);
    -- ERROR: PRIMARY KEY and DISTRIBUTED BY definitions incompatible
  • ジオメトリ型およびカスタムデータ型の列は分散キーとして使用できません。

データスキューのトラブルシューティング

データスキューとは、1 つまたは複数のコンピュートノードが他のノードと比較して著しく多くの行を保持する状態です。一般的な原因は、カーディナリティが低い列(たとえば、多数の行が同一値を共有するステータスフラグや日付列)を選択したことによるものです。その値を持つすべての行は同一ノードにハッシュされ、そのノードが過負荷となり、他のノードは未活用のままとなります。

データスキューの検出方法:各コンピュートノードごとの行数をクエリします。

SELECT gp_segment_id, count(1)
FROM t1
GROUP BY 1
ORDER BY 2 DESC;

 gp_segment_id | count
---------------+--------
             2 | 131191
             0 |     72
             1 |     68
(3 rows)

上記の出力は、ノード 2 がほぼすべてのデータを保持しており、深刻なスキューが発生していることを示しています。

データスキューの修正方法:より均等に分散される値を持つ列に分散キーを変更します。

ALTER TABLE t1 SET DISTRIBUTED BY (c2);

再分散後、データはすべてのコンピュートノードに均等に分散されます。