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

AnalyticDB:テーブル分割の定義

最終更新日:Sep 29, 2024

AnalyticDB for PostgreSQLを使用すると、大きなテーブルをパーティションに分割できます。 条件を使用してデータをクエリすると、システムは指定された条件を満たすパーティションのみをスキャンします。 これにより、テーブル全体のスキャンが防止され、クエリのパフォーマンスが向上します。

サポートされているパーティション分割タイプ

  • 範囲分割: データは、日付などの数値範囲に基づいて分割されます。

  • リストパーティショニング: データは、都市属性などの値のリストに基づいて分割されます。

  • マルチレベル分割: データは数値範囲と値のリストに基づいて分割されます。

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

AnalyticDB for PostgreSQLでは、START値、END値、および範囲内の間隔を定義するEVERY句を指定することで、パーティションを自動的に生成できます。 デフォルトでは、START値は包括的で、END値は排他的です。

日付で範囲分割されたテーブルを作成します。 例:

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') );

数値で範囲分割されたテーブルを作成します。 たとえば、INTデータ型の列をパーティションキーとして使用できます。 例:

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 ); 

リスト分割テーブルの作成

リストパーティションテーブルを作成するときは、値の比較が可能なデータ型を持つ任意の列にパーティションキーを設定できます。また、パーティションキーの指定された値ごとに説明を宣言する必要があります。

リスト分割テーブルを作成します。 例:

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 );

マルチレベルパーティションテーブルの作成

AnalyticDB for PostgreSQLでは、マルチレベルパーティションを持つテーブルを作成できます。 次の例は、3レベルのパーティションテーブルを作成する方法を示しています。 レベル1パーティションのデータは年ごとに範囲分割され、レベル2パーティションのデータは月ごとに範囲分割され、レベル3パーティションのデータは地域ごとにリスト分割されます。 レベル2およびレベル3のパーティションは、サブパーティションと呼ばれます。

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ステートメントを実行して、パーティションをパーティションテーブルに追加できます。 パーティション分割テーブルの作成時にサブパーティションテンプレートが使用されている場合、追加されたパーティションもそれに応じてサブパーティション分割されます。 次の例は、パーティションを追加する方法を示しています。

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ステートメントを使用して、既存のパーティションをサブパーティション化することもできます。 例:

ALTER TABLE sales ALTER PARTITION FOR (RANK(12))
      ADD PARTITION africa VALUES ('africa');
説明

デフォルトのパーティションを持つパーティションテーブルにパーティションを追加することはできません。 このようなパーティションテーブルにパーティションを追加するには、デフォルトのパーティションを分割します。 詳細については、このトピックの「パーティションの分割」セクションをご参照ください。

子パーティションテーブルの名前を指定する

パーティションテーブルを作成するときに、WITH(tablename=<tablename_1>) 句を使用して、AnalyticDB for PostgreSQL V6.3.10.9の子パーティションテーブルの名前を指定できます。

サンプル文:

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')
);

パーティションを分割する

ALTER TABLEステートメントを実行して、パーティションを2つのパーティションに分割できます。 パーティション分割には、次の制限があります。

  • サブパーティションが存在する場合、下位レベルのサブパーティションのみを分割できます。

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

たとえば、1月2017日のデータを含むパーティションが2つのパーティションに分割されているとします。 第1のパーティションは1月1日から1月15日までのデータを含み、第2のパーティションは1月16日から1月31日までのデータを含む。 例:

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);

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

パーティションテーブルを使用する場合、パーティションの粒度を決定する必要があります。 たとえば、テーブルを時間でパーティション分割するには、日、週、または月の粒度を選択できます。 より細かい粒度は、各パーティションにおいてより少ないデータをもたらすが、より多くのパーティションをもたらす。 パーティションの数は絶対標準では測定されません。 各テーブルに200個以下のパーティションを割り当てることを推奨します。 パーティションの数が多いと、データベースのパフォーマンスが低下する場合があります。 たとえば、クエリオプティマイザが実行計画を生成するのに時間がかかるか、VACUUM操作が完了するのに時間がかかります。

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

AnalyticDB for PostgreSQLは、パーティションテーブルのパーティションプルーニングをサポートして、クエリパフォーマンスを向上させます。 パーティションプルーニングが有効になっている場合、システムはテーブル全体をスキャンするのではなく、クエリ条件に基づいて必要なパーティションのみをスキャンします。 例:

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

上記の例では、クエリ条件は、レベル1パーティション2008のレベル2パーティション1のレベル3パーティションusaにあります。 したがって、レベル3パーティションusa内のデータのみがクエリ中にスキャンされる。 次の実行計画では、468レベル3パーティションの1つだけをスキャンする必要があることを示しています。

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

パーティション定義の照会

次のSQL文を実行して、テーブル内のすべてのパーティションの定義を照会できます。

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

パーティション分割テーブルの維持

パーティションテーブルでパーティションを管理できます。 たとえば、パーティションの追加、削除、名前変更、切り捨て、交換、および分割を行うことができます。 詳細については、「大きなテーブルのパーティション化」をご参照ください。

子パーティション分割テーブルの名前変更

子パーティションテーブルの名前は、AnalyticDB for PostgreSQL V6.3.10.9で変更できます。

子パーティションテーブルの名前をpartition_with_name_list_p1からpartition_with_name_list_p1rに変更するためのサンプルステートメント:

ALTER TABLE partition_with_name_list_p1 RENAME TO partition_with_name_list_p1r;

よくある質問

Q: テーブルのパーティションキーを指定するにはどうすればよいですか?

A: テーブルに主キーがある場合は、主キー列をパーティションキーとして指定する必要があります。 テーブルに主キーがない場合は、任意の列をパーティションキーとして指定できます。