このトピックでは、PolarDB for PostgreSQL におけるパーティションテーブルのメリットと特徴について説明します。
概要
PolarDB for PostgreSQL データベースでは、パーティションテーブルとは、パーティションと呼ばれる、より小さく管理しやすい部分に物理的に分割されたテーブルまたはインデックスのことです。各パーティションは、固有の名前とオプションのストレージ属性を持つ独立したオブジェクトです。データベース管理者の視点から見ると、パーティションテーブルには複数の部分があり、それらをまとめて、または個別に管理できるため、管理者はパーティションテーブルを管理する上で大きな柔軟性が得られます。しかし、アプリケーションの視点から見ると、パーティションテーブルはパーティション分割されていないテーブルと同一です。パーティションテーブルにアクセスするために、SQL クエリやデータ操作言語 (DML) ステートメントを修正する必要はありません。
テーブルの各パーティションは、列名、データ型、制約などの論理属性が同一である必要があります。一方で、各パーティションは、圧縮の有効化または無効化、物理ストレージ設定、テーブル空間など、個別の物理属性を持つことができます。
パーティションテーブルは多くの種類のアプリケーションで有用であり、特に大量のデータを管理するアプリケーションに適しています。オンライン トランザクション処理 (OLTP) データベースでは、管理性と可用性の向上によるメリットを得られる場合が多くあります。オンライン分析処理 (OLAP) データウェアハウスでは、パフォーマンスと管理性の向上によるメリットを得られます。
シナリオ
-
データベースサーバーの物理メモリを超える場合 (例:テーブルが 2 TB を超える場合) に、テーブルをパーティション化すると、パフォーマンスが向上します。
-
大規模テーブルに履歴データが格納され、新しいデータが最新のパーティションに書き込まれる場合に、パーティションテーブルを使用します。例えば、テーブルに 12 か月分のデータを格納し、当月分を更新可能なパーティション、過去月分を読み取り専用パーティションに格納します。
メリット
クエリパフォーマンスの向上
場合によっては、特にテーブル内で最も頻繁にアクセスされる行が単一のパーティション、または少数のパーティションに存在する場合に、クエリパフォーマンスが大幅に向上します。パーティション化はインデックスの上位レベルを実質的に置き換えるため、インデックスの頻繁に使用される部分がメモリに収まりやすくなります。クエリまたは更新が単一のパーティション、または少数のパーティションにアクセスする場合、インデックスではなく、そのパーティションのシーケンシャルスキャンが使用されるため、パフォーマンスが向上することがあります。これにより、テーブル全体に散在するランダムアクセス読み取りを回避できます。
管理の簡素化
パーティション化されたオブジェクトは、まとめて、または個別に管理できる部分で構成されます。DDL ステートメントは、テーブルやインデックス全体ではなく、パーティションに対して操作できます。これにより、テーブルの再インデックスなど、リソース負荷の高いタスクを分割して実行できます。テーブルパーティションは 1 つずつ移動できます。問題が発生した場合でも、テーブル全体の移動ではなく、該当パーティションの移動のみをやり直せば済みます。また、パーティショニング設計で利用パターンを考慮しておけば、パーティションの追加または削除によって、バッチロードや削除を実行できます。
DROP TABLEを使用して単一のパーティションを削除する、またはALTER TABLE DETACH PARTITIONを実行する方が、バッチ処理よりもはるかに高速です。これらのコマンドは、バッチ DELETE によって発生する VACUUM のオーバーヘッドも完全に回避します。リソースの競合の低減
一部の OLTP システムでは、パーティション化によって共有リソースの競合を低減できます。たとえば、DML を 1 つのパーティションではなく複数のパーティションに分散できます。
可用性の向上
特定のパーティションが利用できない場合でも、テーブル全体が利用できないことを意味しません。クエリオプティマイザは、参照されていないパーティションをクエリプランから自動的に除外します。そのため、パーティションが利用できない場合でもクエリは影響を受けません。
ストレージコストの削減
使用頻度の低いデータを、低コストで低速なストレージメディアに移動することで、コストを削減できます。
パーティションテーブルのメリットは、通常、テーブルが非常に大きい場合にのみ発揮されます。単一テーブルのサイズがデータベース サーバーの物理メモリを超える場合は、パーティションテーブルの使用を検討してください。
パーティションテーブルの機能
パーティションテーブルの内部実装は標準テーブルより複雑ですが、この複雑さはユーザーからは透過的です。パーティションテーブルの管理と使用方法も標準テーブルとは異なります。これらの機能を明確に理解することで、パーティションテーブルを正しく効率的に使用できます。
例 1:
CREATE TABLE measurement (
city_id int not null,
logdate date not null,
peaktemp int,
unitsales int
) PARTITION BY RANGE (logdate);
CREATE TABLE measurement_y2006m02 PARTITION OF measurement
FOR VALUES FROM ('2006-02-01') TO ('2006-03-01');
CREATE TABLE measurement_y2006m03 PARTITION OF measurement
FOR VALUES FROM ('2006-03-01') TO ('2006-04-01');
...
CREATE TABLE measurement_y2007m11 PARTITION OF measurement
FOR VALUES FROM ('2007-11-01') TO ('2007-12-01');
CREATE TABLE measurement_y2007m12 PARTITION OF measurement
FOR VALUES FROM ('2007-12-01') TO ('2008-01-01')
TABLESPACE fasttablespace;
CREATE TABLE measurement_y2008m01 PARTITION OF measurement
FOR VALUES FROM ('2008-01-01') TO ('2008-02-01')
WITH (parallel_workers = 4)
TABLESPACE fasttablespace;パーティションキー
パーティションキーとは、パーティションテーブル内の各行がどのパーティションに属するかを決定する列、または列の組み合わせのことです。パーティションテーブルでは、各行が明示的にパーティションに割り当てられている必要があります。PolarDB for PostgreSQL は、パーティションキーを使用して、insert、update、および delete 操作を自動的に正しいパーティションに振り分けます。
例 1 では、logdate が measurement テーブルのパーティションキーです。measurement テーブルの各パーティションの境界は、logdate の値のレンジによって決まります。
パーティショニング戦略
PolarDB for PostgreSQL は、データベースがデータをパーティションに配置する方法を制御する、いくつかのパーティショニング戦略を提供します:
レンジパーティショニング
テーブルは、パーティションキーで定義される「レンジ」に基づいてパーティション化されます。異なるパーティションに割り当てられる値のレンジは重複しません。たとえば、日付レンジ、または特定のビジネスオブジェクトの識別子レンジでパーティション化できます。各レンジの境界は、下限を含み、上限を含みません。たとえば、あるパーティションのレンジが 1 から 10、次のパーティションのレンジが 10 から 20 の場合、値 10 は最初のパーティションではなく 2 つ目のパーティションに属します。例 1 の
measurementテーブルは、レンジパーティション化テーブルです。インターバルレンジパーティショニングは、レンジパーティショニングの拡張です。詳細については、「インターバルレンジパーティショニング」をご参照ください。
リストパーティショニング
例 2:
CREATE TABLE department(deptno INT4 Primary Key,dname VARCHAR(50), location VARCHAR(100)) PARTITION BY LIST (deptno); CREATE TABLE department_p1 partition of department for values in (10, 20); CREATE TABLE department_p2 partition of department for values in (30, 40);リストパーティショニングでは、各パーティションに出現するキー値を明示的に列挙して、テーブルをパーティションに分割します。例 2 の
departmentテーブルはリストパーティショニングを使用しています。パーティションキー値は、各パーティションに対して明示的に指定されます。たとえば、department_p1にはdeptnoが10または20の行のみが格納されます。department_p2にはdeptnoが30または40の行のみが格納されます。ハッシュパーティショニング
ハッシュパーティショニングでは、各パーティションに法と剰余を指定して、テーブルをパーティションに分割します。各パーティションには、パーティションキーのハッシュ値を指定した法で割った剰余が、指定した剰余になる行が格納されます。
例 3:
create table idxpart (i int) partition by hash (i); create table idxpart0 partition of idxpart for values with (modulus 2, remainder 0); create table idxpart1 partition of idxpart for values with (modulus 2, remainder 1);例 3 の
idxpartテーブルは、ハッシュパーティショニングを使用しています。たとえば、idxpart0には、iのハッシュ値を 2 で割った剰余が 0 の行が格納されます。idxpart1には、iのハッシュ値を 2 で割った剰余が 1 の行が格納されます。
多段パーティショニング
パーティションテーブルをパーティションに分割した後、これらのパーティションをさらにパーティション化できます。このようなパーティションテーブルを、多段パーティション化テーブルと呼びます。
PolarDB for PostgreSQL では、現在、パーティショニングレベルの数に制限はありません。ただし、レベルが多すぎるとパーティションテーブルの管理が困難になり、クエリパフォーマンスが低下する可能性もあるため、作成しすぎないようにしてください。一般的に、パーティショニングの深さは 3 以下にすることが推奨されます。
段ごとに異なるパーティショニング戦略を使用できます。たとえば、1 段目にレンジパーティショニング、2 段目にハッシュパーティショニング、3 段目にリストパーティショニングを使用できます。
例 4:
CREATE TABLE measurement (
city_id int not null,
logdate date not null,
peaktemp int,
unitsales int
) PARTITION BY RANGE (logdate);
CREATE TABLE measurement_y2006m03 PARTITION OF measurement
FOR VALUES FROM ('2006-03-01') TO ('2006-04-01') PARTITION BY Hash (city_id);
CREATE TABLE measurement_y2006m03_hash1 PARTITION OF measurement_y2006m03
for values with (modulus 2, remainder 0) PARTITION BY List (peaktemp);
CREATE TABLE measurement_y2006m03_hash1_l1 PARTITION OF measurement_y2006m03_hash1 for values in (10, 20);構文
パーティションテーブルの作成、パーティションの追加、パーティションのマージ、パーティションの分割、パーティションの削除など、各パーティションタイプに関連するコマンドと説明については、「パーティションテーブルのコマンド」をご参照ください。