OceanBaseデータベースのパーティション交換機能は、主にパーティションテーブルへのデータを迅速にインポートし、効率的なデータロードを実現するために使用されます。具体的には、フルダイレクトロードにより新規作成された非パーティションテーブルにデータを高速にインポートした後、パーティション交換機能を利用して非パーティションテーブル内のデータをパーティションテーブルに高速にインポートし、既存のパーティションテーブルへの増分データインポート性能を向上させます。
パーティション交換機能は、増分ダイレクトロードの代替案として利用することを推奨します。例えば、パーティション交換機能を利用してパーティションテーブルAの増分データをインポートする手順は以下の通りです:
- テーブルAに空の新しいパーティションPを作成します。
- テーブルAと構造が完全に同じ非パーティションテーブルBを新規作成し、ダイレクトロードによって増分データをテーブルBにインポートします。
- パーティション交換機能を利用して、テーブルAの新しいパーティションPとテーブルBを交換します。
サポートされているパーティション交換の状況
パーティション交換のサポート状況は以下の表のとおりです。ここで、タイプの列はターゲットテーブル(target_partition_table_name)を、タイプの行はソーステーブル(origin_table_name)を表します。
タイプ |
非パーティションテーブル |
パーティションテーブル |
サブパーティションテーブル |
|---|---|---|---|
| パーティションテーブル | サポート | 不支持 | 不支持 |
| サブパーティションテーブルのパーティション | 不支持 | サポート | 不支持 |
| サブパーティションテーブルのサブパーティション | サポート | 不支持 | 不支持 |
制限事項と注意点
データ検証はサポートされていないため、
WITHOUT VALIDATIONを指定する必要があります。ユーザーは交換データの有効性を自己保証する必要があります。パーティションテーブルと非パーティションテーブルのテーブルレベルおよび列レベルの属性要件は、一対一で対応している必要があります。
パーティションテーブルと非パーティションテーブルの制約要件は完全に同じであり、現在のバージョンでは両テーブル間で外部キー制約を持つことはサポートされていません。
パーティションテーブルのローカルインデックステーブルと非パーティションテーブルのインデックステーブルは、一対一で対応している必要があります。
INCLUDING INDEXESの動作のみがサポートされています(OracleモードではINCLUDING INDEXESを明示的に指定する必要があります)。ローカルインデックスが対応するパーティションのデータも交換に含まれ、交換後も交換前と同じ可用状態を維持します。UPDATE GLOBAL INDEXESはサポートされていないため、グローバルインデックスは交換成功後すべて Unusable 状態(無効状態)になります。現在のパーティション交換機能は、増分ダイレクトロードの一時的な代替機能としてのみ利用することを推奨します。増分ダイレクトロードの詳細については、ダイレクトロードの概要を参照してください。
パーティションテーブルと非パーティションテーブルのデータ交換を行う場合:
- パーティションは Range/List パーティションである必要があります。
サブパーティションテーブルのサブパーティションと非パーティションテーブルのデータ交換を行う場合:
- パーティションの種類に制限はありませんが、サブパーティションは Range パーティションである必要があります。
サブパーティションテーブルのパーティションとパーティションテーブルのデータ交換を行う場合:
target_partition_table_nameはサブパーティションテーブルである必要があり、交換するパーティションはそのテーブルのパーティション名である必要があります。また、そのサブパーティションテーブルのパーティションは Range/List パーティションである必要があります。origin_table_nameはパーティションテーブルである必要があり、そのパーティションの種類は交換用のパーティションの下のサブパーティションと完全に一致している必要があります。- パーティションテーブルとサブパーティションテーブルを交換した後、関連するテーブルの統計情報は無効になり、再収集が必要です。
構文
ALTER TABLE target_partition_table_name
EXCHANGE {PARTITION partition_name
| SUBPARTITION subpartition_name}
WITH TABLE origin_table_name
INCLUDING INDEXES
WITHOUT VALIDATION;
パラメータ説明
パラメータ |
説明 |
|---|---|
| target_partition_table_name | パーティション交換におけるターゲットパーティションテーブル名を表します。 |
| PARTITION partition_name | パーティション交換におけるターゲットパーティションテーブルのパーティション名を指定します。 |
| SUBPARTITION subpartition_name | パーティション交換におけるターゲットパーティションテーブルのサブパーティション名を指定します。 |
| origin_table_name | パーティション交換におけるソーステーブル名を表します。非パーティションテーブルまたはパーティションテーブルです。 |
使用方法
現在のパーティション交換機能は、パーティションテーブルの1つのパーティションと非パーティションテーブルとのデータ交換を実現しており、主に増分ダイレクトロード機能の一時的な代替ツールとして使用されます。ここで、パーティションテーブルと非パーティションテーブルの一般的な特性は以下のとおりです:
- パーティションテーブル(partitioned table):履歴データを含むパーティションテーブルで、通常データ量が多い。
- ノンパーティションテーブル(non-partitioned table):増分データを含む。
パーティション交換機能の使用には非常に注意が必要です。不適切な操作により、元のテーブルのパーティションキーの条件に合致しなくなるデータが発生し、連鎖エラーを引き起こす可能性があるためです。そのため、パーティション交換を実行する際には、以下の手順に従って、パーティションテーブルとノンパーティションテーブルがパーティション交換を行えるかどうかを判断する必要があります。
SHOW CREATE TABLEステートメントを使用して、パーティションテーブルのパーティションキーとターゲットパーティション情報を照会します。ノンパーティションテーブルのデータを照会し、ノンパーティションテーブルのデータがターゲットパーティションのパーティションキーのデータ範囲要件を満たしているかどうかを判断します。ここで、
table_nameは照会するテーブル名です。SHOW CREATE TABLE table_name;照会結果に基づき、パーティションテーブルとノンパーティションテーブルが上記の 制限事項および注意点 を満たしていることを確認します。
パーティション交換を行う前に、少なくとも以下の条件を満たしていることを確認する必要があります。
プロパティ要求同一テナント内にあるかどうか はい 同一スキーマ内にあるかどうか はい 同一テーブルグループ(TableGroup)に属するかどうか はい 同一テーブル領域(TableSpace)に属するかどうか はい 使用する文字セット形式が一致しているかどうか はい テーブルタイプが一致しているかどうか はい。両方ともユーザーテーブル、つまり USER_TABLEである必要があります主キーの数が一致しているかどうか はい 行ストレージ形式が一致しているかどうか はい 列形式と列の相対順序が一致しているかどうか はい 両方とも自動インクリメント列であるかどうか はい 列のデフォルト値や生成列式が一致しているかどうか はい 暗号化方式が一致しているかどうか はい カラムストア形式が一致しているかどうか はい インデックス形式、状態、数が一致しているかどうか はい。パーティションテーブルのローカルインデックスは、ノンパーティションテーブルのインデックスと一対一で対応している必要があります インデックステーブル名が一致しているかどうか いいえ 制約の形式や含まれる列が一致しているかどうか はい パーティション交換の構文を使用してパーティション交換を行います。交換後、パーティションテーブルの指定されたパーティションのデータはノンパーティションテーブルに移行され、ノンパーティションテーブルのデータはパーティションテーブルの指定されたパーティションに移行されます。パーティションテーブルのグローバルインデックスの状態は Unusable になります。
例
例1:RANGEパーティションテーブルと非パーティションテーブルのデータ交換
RANGEパーティションテーブルと非パーティションテーブルのデータを交換します。
RANGEパーティションテーブル
tbl1_rを作成します。obclient> CREATE TABLE tbl1_r (col1 INT PRIMARY KEY, col2 VARCHAR2(50)) PARTITION BY RANGE(col1) (PARTITION p0 VALUES LESS THAN(10), PARTITION p1 VALUES LESS THAN(20), PARTITION p2 VALUES LESS THAN(30) );非パーティションテーブル
tbl1を作成します。obclient> CREATE TABLE tbl1 (col1 INT PRIMARY KEY, col2 VARCHAR2(50));テーブル
tbl1にデータを挿入します。obclient> INSERT INTO tbl1 VALUES(1, 'a1'),(2, 'a2');実行結果は次のとおりです:
Query OK, 2 rows affected Records: 2 Duplicates: 0 Warnings: 0パーティションテーブル
tbl1_rのパーティションp0と非パーティションテーブルtbl1の間でパーティション交換を実行します。obclient> ALTER TABLE tbl1_r EXCHANGE PARTITION p0 WITH TABLE tbl1 INCLUDING INDEXES WITHOUT VALIDATION;パーティションテーブル
tbl1_rのパーティションp0のデータを確認します。obclient> SELECT * FROM tbl1_r PARTITION(p0);実行結果は次のとおりです:
+------+------+ | COL1 | COL2 | +------+------+ | 1 | a1 | | 2 | a2 | +------+------+ 2 rows in set
LISTパーティションテーブルと非パーティションテーブルのデータを交換します。
LISTパーティションテーブル
tbl1_lを作成します。obclient> CREATE TABLE tbl1_l (col1 INT, col2 VARCHAR(50), col3 INT) PARTITION BY LIST(col3) (PARTITION p0 VALUES (1, 2, 3, 4), PARTITION p1 VALUES (5, 6, 7, 8, 9), PARTITION p2 VALUES (DEFAULT) );非パーティションテーブル
tbl1_2を作成します。obclient> CREATE TABLE tbl1_2 (col1 INT, col2 VARCHAR(50), col3 INT);テーブル
tbl1_2にデータを挿入します。obclient> INSERT INTO tbl1_2 VALUES(1, 'a1', 1), (2, 'a2', 2), (3, 'a3', 3), (4, 'a4', 4), (5, 'a5', 5);実行結果は次のとおりです:
Query OK, 5 rows affected Records: 5 Duplicates: 0 Warnings: 0パーティションテーブル
tbl1_lのパーティションp0と非パーティションテーブルtbl1_2の間でパーティション交換を実行します。obclient> ALTER TABLE tbl1_l EXCHANGE PARTITION p0 WITH TABLE tbl1_2 INCLUDING INDEXES WITHOUT VALIDATION;パーティションテーブル
tbl1_lのパーティションp0のデータを確認します。obclient> SELECT * FROM tbl1_l PARTITION(p0);実行結果は次のとおりです:
+------+------+------+ | COL1 | COL2 | COL3 | +------+------+------+ | 1 | a1 | 1 | | 2 | a2 | 2 | | 3 | a3 | 3 | | 4 | a4 | 4 | | 5 | a5 | 5 | +------+------+------+ 5 rows in set
例2:サブパーティションテーブルのパーティションとパーティションテーブルのデータ交換
Range + Hash サブパーティションテーブル
tbl2_rhを作成します。obclient> CREATE TABLE tbl2_rh (col1 INT PRIMARY KEY, col2 INT) PARTITION BY RANGE(col1) SUBPARTITION BY HASH(col1) SUBPARTITIONS 5 (PARTITION p0 VALUES LESS THAN (10), PARTITION p1 VALUES LESS THAN (20), PARTITION p2 VALUES LESS THAN (30), PARTITION p3 VALUES LESS THAN (MAXVALUE) );Hash パーティションテーブル
tbl2_hを作成します。obclient> CREATE TABLE tbl2_h (col1 INT PRIMARY KEY, col2 INT) PARTITION BY HASH(col1) PARTITIONS 5;テーブル
tbl2_rhにデータを挿入します。obclient> INSERT INTO tbl2_rh VALUES(11, 30), (14, 40), (26, 150), (29, 160);実行結果は次のとおりです:
Query OK, 4 rows affected Records: 4 Duplicates: 0 Warnings: 0パーティションテーブル
tbl2_rhのパーティションp1のデータを確認します。obclient> SELECT * FROM tbl2_rh PARTITION(p1);実行結果は次のとおりです:
+------+------+ | COL1 | COL2 | +------+------+ | 11 | 30 | | 14 | 40 | +------+------+ 2 rows in setテーブル
tbl2_hにデータを挿入します。obclient> INSERT INTO tbl2_h VALUES(12, 20), (16, 110), (17, 170), (19, 120);実行結果は次のとおりです:
Query OK, 4 rows affected Records: 4 Duplicates: 0 Warnings: 0サブパーティションテーブル
tbl2_rhのパーティションp1とパーティションテーブルtbl2_hの間でパーティション交換を実行します。obclient> ALTER TABLE tbl2_rh EXCHANGE PARTITION p1 WITH TABLE tbl2_h INCLUDING INDEXES WITHOUT VALIDATION;パーティションテーブル
tbl2_rhのパーティションp1のデータを確認します。obclient> SELECT * FROM tbl2_rh PARTITION(p1);実行結果は次のとおりです:
+------+------+ | COL1 | COL2 | +------+------+ | 19 | 120 | | 12 | 20 | | 16 | 110 | | 17 | 170 | +------+------+ 4 rows in set
例3:サブパーティションテーブルのサブパーティションと非パーティションテーブルとのデータ交換
Range + Range サブパーティションテーブル
tbl3_rrを作成します。obclient> CREATE TABLE tbl3_rr(col1 INT, col2 INT) PARTITION BY RANGE(col1) SUBPARTITION BY RANGE(col2) (PARTITION p0 VALUES LESS THAN(10) (SUBPARTITION sp0 VALUES LESS THAN(20), SUBPARTITION sp1 VALUES LESS THAN(50), SUBPARTITION sp2 VALUES LESS THAN (MAXVALUE) ), PARTITION p1 VALUES LESS THAN(20) (SUBPARTITION sp3 VALUES LESS THAN(20), SUBPARTITION sp4 VALUES LESS THAN(50), SUBPARTITION sp5 VALUES LESS THAN (MAXVALUE) ) );非パーティションテーブル
tbl3を作成します。obclient> CREATE TABLE tbl3 (col1 INT, col2 INT);テーブル
tbl3_rrにデータを挿入します。obclient> INSERT INTO tbl3_rr VALUES(1, 30), (4, 40), (16, 150), (19, 160);実行結果は次のとおりです:
Query OK, 4 rows affected Records: 4 Duplicates: 0 Warnings: 0パーティションテーブル
tbl3_rrのパーティションsp1のデータを確認します。obclient> SELECT * FROM tbl3_rr PARTITION(sp1);実行結果は次のとおりです:
+------+------+ | COL1 | COL2 | +------+------+ | 1 | 30 | | 4 | 40 | +------+------+ 2 rows in setテーブル
tbl3にデータを挿入します。obclient> INSERT INTO tbl3 VALUES(2, 21), (6, 30), (7, 35), (9, 40);実行結果は次のとおりです:
Query OK, 4 rows affected Records: 4 Duplicates: 0 Warnings: 0パーティションテーブル
tbl3_rrのパーティションsp1と非パーティションテーブルtbl3との間でパーティション交換を実行します。obclient> ALTER TABLE tbl3_rr EXCHANGE SUBPARTITION sp1 WITH TABLE tbl3 INCLUDING INDEXES WITHOUT VALIDATION;パーティションテーブル
tbl3_rrのパーティションsp1のデータを確認します。obclient> SELECT * FROM tbl3_rr PARTITION(sp1);実行結果は次のとおりです:
+------+------+ | COL1 | COL2 | +------+------+ | 2 | 21 | | 6 | 30 | | 7 | 35 | | 9 | 40 | +------+------+ 4 rows in set