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の場合に使用します。 |
使用方法
現在のパーティション交換機能は、パーティションテーブルの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