このトピックでは、 PolarDB for PostgreSQL (Compatible with Oracle) クラスターのパーティションテーブルの機能と利点の概要について説明します。
概要
PolarDB for PostgreSQL (Compatible with Oracle) クラスターでは、テーブルまたはインデックスをパーティションと呼ばれる小さな部分に物理的に分割して、管理を容易にできます。 各パーティションは、独自の名前とストレージプロパティを持つオブジェクトです。 データベース管理者の場合、パーティションは一括または個別に管理でき、作業の柔軟性が向上します。 アプリケーションにとって、パーティションテーブルには、非パーティションテーブルとの違いはありません。 パーティションテーブルをクエリするときに、SQL文やDMLコマンドを変更する必要はありません。
パーティションテーブルのパーティションには、列名、データ型、制約などの論理プロパティが同じである必要がありますが、圧縮ステータス、物理ストレージ設定、テーブルスペースなど、異なる物理プロパティを持つことができます。
パーティショニングは、多くのタイプのアプリケーション、特に大量のデータを含むアプリケーションに利点を提供します。 オンライントランザクション処理 (OLTP) データベースの場合、パーティショニングにより管理性と可用性が向上します。 オンライン分析処理 (OLAP) データベースの主な利点は、パフォーマンスと管理性にあります。
シナリオ
テーブルスペースがデータベースサーバーの物理メモリよりも大きい場合など、テーブルが大きすぎる場合は、テーブルをパーティション化します。 これにより、データベースのパフォーマンスが向上します。 たとえば、テーブルのサイズが2 GBを超える場合は、テーブルをパーティション分割することができます。
履歴データを格納するときに大きなテーブルをパーティション化し、新しいデータを最新のパーティションに書き込む必要があります。 たとえば、大きなテーブルを使用して1年間のデータを保存する場合にこれを実行できます。 最新の月のデータを別の更新可能なパーティションに保存し、前の月のデータを他の読み取り専用パーティションに保存できます。
メリット
より高いパフォーマンス
特に、最も頻繁にアクセスされる行を1つまたはいくつかのパーティションに制限できる場合、パーティションを分割するとクエリのパフォーマンスが大幅に向上します。 分割は、インデックスツリーの上位レベルを置き換える。 クエリに1つまたはいくつかの特定のパーティションが含まれる場合、データベースシステムは、インデックスに依存するのではなく、それらのパーティションに対してのみシーケンシャルスキャンを実行できます。 これにより、システムはテーブル全体に分散したレコードではなく、連続したデータチャンクを処理するため、パフォーマンスと管理性が向上します。
より簡単な管理
スタンドアロンオブジェクトとして、パーティションは個別にまたはまとめて管理でき、DDL操作はテーブル全体またはインデックス全体ではなく、パーティションに対して実行できます。 したがって、インデックスやテーブルの再構築など、リソースを大量に消費するタスクを分解できます。一度に1つのパーティションを削除できます。 問題が発生した場合は、テーブル全体ではなく、関連するパーティションのみを移動する必要があります。 パーティションを単位としてデータレコードに対してバッチ操作を実行することもできます。 たとえば、テーブルからデータを削除する場合は、DROP tableを使用して関連するパーティションを削除するか、ALTER TABLE DETACH partitionを使用して親テーブルからパーティションを削除するだけです。 VACUUM操作は、これらの操作の後にストレージスペースを再利用する必要がありません。これは、バッチ削除に勝るもう1つの利点です。
リソース競合の削減
一部のOLTPデータベースでは、パーティション分割により、DMLステートメントが複数のパーティションで実行される場合など、リソースの競合を減らすことができます。
より高い可用性
パーティションが使用できなくなった場合でも、残りのパーティションテーブルにアクセスできます。 クエリオプティマイザーは、クエリへの影響を回避するために、使用できないパーティションをクエリプランから自動的に削除します。
低ストレージコスト
アクセス頻度の低いパーティションを低速で安価なストレージメディアにダンプして、コストを削減できます。
上記の利点は、パーティションテーブルのサイズが大きい場合にのみ有効です。 テーブルのサイズがデータベースサーバーの物理メモリのサイズに達したら、テーブルをパーティション化することをお勧めします。
仕組み
パーティショニングは構造を複雑にしますが、これはユーザーには透過的です。 このセクションでは、パーティショニングの特性とメカニズムについて説明します。 この情報を理解すると、パーティションテーブルを効果的に使用できます。
例 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 (Compatible with Oracle) は、パーティションキーに基づいて、挿入、更新、削除などの操作を関連するパーティションに自動的にルーティングします。
例1では、logdateはmeasurementという名前のパーティションテーブルのパーティションキーです。 テーブルmeasurementのパーティションの境界は、logdate値によって決まります。
パーティション分割方法
PolarDB for PostgreSQL (Compatible with Oracle) は、複数のパーティション分割方法をサポートしています。
範囲分割
範囲分割は、ビジネスの日付範囲や識別子範囲など、パーティションキーの値の範囲に基づいてテーブルを分割します。 各範囲の境界は、下端を含み、上端を含まない。 例えば、第1のパーティションの値の範囲が1から10であり、第2のパーティションの値の範囲が10から20である場合、10は第1のパーティションではなく第2のパーティションに属する。 実施例1における
測定テーブルは、範囲分割テーブルである。区間範囲分割は、範囲分割から拡張された分割方法です。 詳細については、「間隔範囲のパーティション分割」をご参照ください。
リスト分割
例 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_p1 partition of department for values in (30, 40);リスト分割は、離散値のリストに基づいてテーブルを分割します。 例2の
部門テーブルは、リスト分割テーブルです。 テーブルの2つのパーティションは、パーティションキーの特定の値のみを含むように明示的に定義されます。 たとえば、depart_p1パーティションにはdeptno値が10または20の行のみが格納され、depart_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);この例では、
idxpartテーブルはハッシュ分割されています。idxpart0パーティションには、iを2で割ったハッシュ値の余りが0の行のみが格納されます。idxpart1パーティションには、iを2で割ったハッシュ値の余りが1である行のみが格納されます。
マルチレベルパーティション分割
マルチレベル分割とは、既に分割されたテーブルを分割する方法を指す。
PolarDB for PostgreSQL (Compatible with Oracle) は無制限のパーティショニングレベルをサポートしますが、3つ以上のレベルを作成しないことを推奨します。 過度のパーティショニングレベルは、パーティションの管理性を損ない、クエリのパフォーマンスに悪影響を与える可能性があります。
さまざまなパーティショニングレベルでさまざまなパーティショニングメソッドを使用できます。 たとえば、最初のレベルには範囲分割、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);構文
パーティションの作成、追加、マージ、分割、削除など、パーティションを管理するためのステートメントの詳細については、「パーティションテーブルのコマンドリスト」をご参照ください。