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

AnalyticDB:パーティションテーブルの定義

最終更新日:Mar 28, 2026

AnalyticDB for PostgreSQL では、大規模なテーブルを複数のパーティションに分割できます。これにより、クエリはフィルター条件に一致するパーティションのみをスキャンし、全表スキャンを回避してクエリパフォーマンスを向上させます。

パーティション化を利用するタイミング

以下の 3 つの条件がすべて満たされる場合に、パーティション化の効果が最も高まります。

  • テーブルが大規模であること。 行数が非常に多いテーブルは、パーティション化の対象として適しています。

  • クエリパフォーマンスが不十分であること。 クエリの応答時間が許容範囲を超えて遅くなる場合にのみ、パーティション化を適用します。

  • クエリの述語に明確なアクセスパターンがあること。 一般的なクエリの WHERE 句を確認してください。同じ列が繰り返し出現する場合、その列は自然なパーティションキー候補となります。

サポートされるパーティション化タイプ

タイプデータの分割方法典型的な利用シーン
範囲パーティション化日付や整数などの数値範囲時系列データ、連番 ID
リストパーティション化値の明示的なリストカテゴリデータ(例:リージョン、ステータス)
多段パーティション化複数のレベルで範囲パーティション化とリストパーティション化を組み合わせた方式複数のフィルターディメンションを持つ大規模データセット

パーティションキーの選択

パーティションキーは、パーティションプルーニングが有効に機能するかどうかを決定します。

  • クエリの述語と一致すること。 WHERE 句に最も頻繁に出現する列または列群を選択します。パーティションプルーニングは、クエリ条件にパーティションキーが含まれる場合にのみ有効です。

  • データ保持戦略と整合性を保つこと。 旧データを定期的に一括削除する場合は、削除対象のデータが単一のパーティションに収まるようにパーティションを設計します。DELETE 文を実行するよりも、パーティションを削除(DROP PARTITION)する方がはるかに高速です。

  • プライマリキー制約への準拠。 テーブルにプライマリキーが定義されている場合、パーティションキーは必ずプライマリキー列のいずれかでなければなりません。プライマリキーが未定義の場合は、任意の列をパーティションキーとして指定できます。

範囲パーティション化テーブルの作成

STARTENDEVERY を指定することで、指定範囲内のパーティションを自動生成できます。START はデフォルトで包含(inclusive)、END は排他(exclusive)です。

日付によるパーティション化:

CREATE TABLE sales (id int, date date, amt decimal(10,2))
DISTRIBUTED BY (id)
PARTITION BY RANGE (date)
( START (date '2016-01-01') INCLUSIVE
   END (date '2017-01-01') EXCLUSIVE
   EVERY (INTERVAL '1 day') );

整数によるパーティション化(デフォルトパーティションあり):

CREATE TABLE rank (id int, rank int, year int, gender char(1), count int)
DISTRIBUTED BY (id)
PARTITION BY RANGE (year)
( START (2006) END (2016) EVERY (1),
  DEFAULT PARTITION extra );
DEFAULT PARTITION は、定義済みのすべての範囲外に該当する行をキャッチします。

リストパーティション化テーブルの作成

パーティションキーには、値比較をサポートするデータの型を持つ任意の列を指定できます。各パーティションに対して値の説明を宣言します。

CREATE TABLE rank (id int, rank int, year int, gender
char(1), count int )
DISTRIBUTED BY (id)
PARTITION BY LIST (gender)
( PARTITION girls VALUES ('F'),
  PARTITION boys VALUES ('M'),
  DEFAULT PARTITION other );

多段パーティション化テーブルの作成

以下の例では、3 段階のパーティション化テーブルを作成します。

  • 第 1 段階: year 列による範囲パーティション化

  • 第 2 段階(サブパーティション): month 列による範囲パーティション化

  • 第 3 段階(サブパーティション): region 列によるリストパーティション化

CREATE TABLE sales (id int, year int, month int, day int,
region text)
DISTRIBUTED BY (id)
PARTITION BY RANGE (year)
    SUBPARTITION BY RANGE (month)
       SUBPARTITION TEMPLATE (
        START (1) END (13) EVERY (1),
        DEFAULT SUBPARTITION other_months )
           SUBPARTITION BY LIST (region)
             SUBPARTITION TEMPLATE (
               SUBPARTITION usa VALUES ('usa'),
               SUBPARTITION europe VALUES ('europe'),
               SUBPARTITION asia VALUES ('asia'),
               DEFAULT SUBPARTITION other_regions )
( START (2002) END (2012) EVERY (1),
  DEFAULT PARTITION outlying_years );

パーティションの追加

既存のパーティションテーブルにパーティションを追加するには、ALTER TABLE ... ADD PARTITION を使用します。

テーブルがサブパーティショントレムプレートを使用して作成された場合、新規パーティションは自動的にサブパーティション化されます。

ALTER TABLE sales ADD PARTITION
            START (date '2017-02-01') INCLUSIVE
            END (date '2017-03-01') EXCLUSIVE;

サブパーティショントレムプレートが使用されていない場合は、パーティション追加時にインラインでサブパーティションを定義します。

ALTER TABLE sales ADD PARTITION
            START (date '2017-02-01') INCLUSIVE
            END (date '2017-03-01') EXCLUSIVE
      ( SUBPARTITION usa VALUES ('usa'),
        SUBPARTITION asia VALUES ('asia'),
        SUBPARTITION europe VALUES ('europe') );

既存のパーティションをサブパーティション化するには、以下のように記述します。

ALTER TABLE sales ALTER PARTITION FOR (RANK(12))
      ADD PARTITION africa VALUES ('africa');
デフォルトパーティションが定義されたテーブルには、パーティションを直接追加できません。このようなテーブルにパーティションを追加するには、代わりにデフォルトパーティションを分割します。「パーティションの分割」をご参照ください。

パーティション名の指定

AnalyticDB for PostgreSQL V6.3.10.9 以降では、テーブル作成時に WITH(tablename=<tablename>) 句を使用して、パーティションに明示的な名前を割り当てることができます。

CREATE TABLE partition_with_name_list (a int, b int, c int) DISTRIBUTED BY (a) PARTITION BY LIST (a)
(
    PARTITION p1 VALUES (1)  WITH (tablename='partition_with_name_list_p1'),
    PARTITION p2 VALUES (2)  WITH (tablename='partition_with_name_list_p2'),
    PARTITION p3 VALUES (3)  WITH (tablename='partition_with_name_list_p3'),
    PARTITION p4 VALUES (4)  WITH (tablename='partition_with_name_list_p4')
);

パーティションの名前の変更

AnalyticDB for PostgreSQL V6.3.10.9 以降では、以下のコマンドでパーティションの名前を変更できます。

ALTER TABLE partition_with_name_list_p1 RENAME TO partition_with_name_list_p1r;

パーティションの分割

ALTER TABLE ... SPLIT PARTITION を使用すると、1 つのパーティションを 2 つに分割できます。

使用制限:

  • サブパーティションが存在する場合、分割可能なのは最下位レベルのサブパーティションのみです。

  • AT 句で指定した分割値は、2 番目のパーティションに割り当てられます。

既存パーティションの分割:

以下の例では、2017 年 1 月のパーティションを 1 月 16 日で分割します。1 月 1 日~15 日のデータは最初のパーティションに、1 月 16 日~31 日のデータは 2 番目のパーティションに格納されます。

ALTER TABLE sales SPLIT PARTITION FOR ('2017-01-01')
AT ('2017-01-16')
INTO (PARTITION jan171to15, PARTITION jan1716to31);

デフォルトパーティションの分割による新規パーティションの追加:

テーブルにデフォルトパーティションが定義されている場合、それを分割して名前付きパーティションを作成できます。INTO 句では、デフォルトパーティションを 2 番目に指定する必要があります。

ALTER TABLE sales SPLIT DEFAULT PARTITION
START ('2017-01-01') INCLUSIVE
END ('2017-02-01') EXCLUSIVE
INTO (PARTITION jan17, default partition);

パーティション粒度の決定

パーティション粒度は、「各パーティションに格納されるデータ量」と「パーティション総数」のトレードオフを伴います。粒度を細かくすると、各パーティションのデータ量は減少しますが、パーティション総数は増加します。

一般的なガイドラインとして、**1 つのテーブルあたりパーティション数を 200 個以下**に保つことを推奨します。パーティション数が過剰になると、データベースパフォーマンスが低下する可能性があります。例えば、クエリ オプティマイザーが実行計画を生成するのに時間がかかるようになり、VACUUM 操作の完了にもより長い時間がかかるようになります。

パーティションテーブルのクエリ最適化

AnalyticDB for PostgreSQL ではパーティションプルーニングをサポートしています。クエリにパーティションキーに対する条件が含まれている場合、オプティマイザーは全テーブルではなく、条件に一致するパーティションのみをスキャンします。

プルーニングが有効であることを確認する:

EXPLAIN
  SELECT * FROM sales
  WHERE year = 2008
    AND month = 1
    AND day = 3
    AND region = 'usa';

期待される出力(プルーニングが正常に動作している場合):

Gather Motion 4:1  (slice1; segments: 4)  (cost=0.00..431.00 rows=1 width=24)
  ->  Sequence  (cost=0.00..431.00 rows=1 width=24)
        ->  Partition Selector for sales (dynamic scan id: 1)  (cost=10.00..100.00 rows=25 width=4)
              Filter: year = 2008 AND month = 1 AND region = 'usa'::text
              Partitions selected:  1 (out of 468)
        ->  Dynamic Table Scan on sales (dynamic scan id: 1)  (cost=0.00..431.00 rows=1 width=24)
              Filter: year = 2008 AND month = 1 AND day = 3 AND region = 'usa'::text

この実行計画において、Partitions selected: 1 (out of 468) という表示は、プルーニングが有効に機能していることを確認できます。特定のフィルター条件を指定しているにもかかわらず、選択されるパーティション数が非常に多い場合は、フィルター対象の列がパーティションキーと一致しているかを確認してください。

クエリ パーティション定義

テーブル内のすべてのパーティションを照会するには、pg_partitions システムビューをクエリします。

SELECT
  partitionboundary,
  partitiontablename,
  partitionname,
  partitionlevel,
  partitionrank
FROM pg_partitions
WHERE tablename='sales';

関連操作

パーティションの削除、切り捨て(TRUNCATE)、交換(EXCHANGE)など、パーティション管理に関するすべての操作の一覧については、「大規模テーブルのパーティション化」をご参照ください。

よくある質問

パーティションキーはどのように選べばよいですか?

テーブルにプライマリキーが定義されている場合、パーティションキーは必ずプライマリキー列のいずれかでなければなりません。プライマリキーが未定義の場合は、任意の列をパーティションキーとして指定できます。パーティションプルーニングの効果を最大限に発揮するには、WHERE 句に最も頻繁に出現する列を選択してください。