PolarDB-X は、バッチ挿入用の標準構文 INSERT ... VALUES をサポートしています。1 つのステートメントで複数行を挿入するには、以下の構文を使用します:
INSERT [IGNORE] [INTO] table_name(column_name, ...) VALUES (value1, ...), (value2, ...), ...;バッチ挿入のパフォーマンスに影響を与える要因は 6 つあります:バッチサイズ、並列処理の次数(DOP)、シャード数、カラム数、グローバルセカンダリインデックス数、およびシーケンス数です。後者の 4 つはテーブル設計によって決定され、リアルタイムでのチューニング対象外となります。たとえば、グローバルセカンダリインデックスを増やすと読み取りパフォーマンスが向上しますが、書き込みスループットは低下します。
本トピックでは、クエリ実行時にチューニング可能な 2 つの要因 — バッチサイズ および DOP — に焦点を当てます。
クイックリファレンス
| 目的 | バッチサイズ | DOP | ポリシー |
|---|---|---|---|
| 同時実行性とリソース効率のバランスを取る | 1,000 行 | 16–32 | SPLIT(デフォルト) |
| 最大書き込みスループット(32 シャード) | 20,000–50,000 行 | 64–80 | NONE |
| スループットのスケーリング | ノードを追加(線形スケールアップ:90%–100%) | ノード数に応じて増加 | — |
自動分割の仕組み
PolarDB-X は、高い同時実行性を維持し、ノード間の負荷を均等化するために、大規模なバッチ挿入ステートメントを自動的に分割します。ステートメントのサイズが 256 KB を超えると、PolarDB-X はそれを小さなバッチに分割し、シリアルに実行します。この動作は、以下の 3 つのパラメーターで制御されます:
| パラメーター | デフォルト値 | 単位 | 説明 |
|---|---|---|---|
BATCH_INSERT_POLICY | SPLIT | — | SPLIT を設定すると自動分割が有効になり、NONE を設定すると無効になります |
MAX_BATCH_INSERT_SQL_LENGTH | 256 | KB | 自動分割をトリガーするサイズしきい値 |
BATCH_INSERT_CHUNK_SIZE_DEFAULT | 200 | 行 | 分割後の各バッチにおける最大行数 |
自動分割を無効にするには、ステートメントに以下のヒントを追加します:
/*+TDDL:CMD_EXTRA(BATCH_INSERT_POLICY=NONE)*/BATCH_INSERT_POLICY=NONE は、大規模なバッチサイズのテストや、手動によるバッチサイズ制御によるスループット最大化時のみ使用してください。自動分割が無効の場合、PolarDB-X はステートメントを分割しません。その結果、大規模なステートメントはメモリ使用量を増加させ、コンピュートノード間の負荷不均衡を引き起こす可能性があります。
テスト環境
本トピックで示すすべてのベンチマークは、以下の環境で実施されています:
| パラメーター | 値 |
|---|---|
| カーネルバージョン | polarx-kernel_5.4.11-16279028_xcluster-20210802 |
| ノードスペック | 16 コア、64 GB メモリ |
| ノード数 | 4 |
すべてのテストで使用したテーブルスキーマは以下のとおりです:
CREATE TABLE `sbtest1` (
`id` int(11) NOT NULL,
`k` int(11) NOT NULL DEFAULT '0',
`c` char(120) NOT NULL DEFAULT '',
`pad` char(60) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
KEY `k_1` (`k`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;非シャーディングテーブルのパフォーマンス
非シャーディングテーブルは、すべてのデータを単一のデータノード上に格納します。そのパフォーマンスは有用なベースラインとなり、シャーディングテーブルの書き込みスループットは、シャード数にほぼ線形に比例してスケールアップします。
バッチサイズの影響(DOP = 16)
| バッチサイズ(行) | 1 | 10 | 100 | 500 | 1,000 | 2,000 | 5,000 | 10,000 |
|---|---|---|---|---|---|---|---|---|
| スループット(行/秒) | 5,397 | 45,653 | 153,216 | 211,976 | 210,644 | 215,103 | 221,919 | 220,529 |
スループットは 1,000 行で頭打ちになります。それ以上のバッチサイズでは有意な向上は見られず、オプティマイザーが期待通りにクエリを最適化できなくなります。また、BATCH_INSERT_POLICY=NONE を指定して自動分割を無効にする必要があります。
DOP の影響(バッチサイズ = 1,000)
| DOP(スレッド数) | 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128 |
|---|---|---|---|---|---|---|---|---|
| スループット(行/秒) | 22,625 | 41,326 | 76,052 | 127,646 | 210,644 | 223,431 | 190,138 | 160,858 |
スループットは DOP 16–32 でピークに達します。32 スレッドを超えると、スループットは低下します。
非シャーディングテーブルへの推奨事項: バッチサイズを 1,000 行とし、DOP を 16–32 に設定してください。
シャーディングテーブルのパフォーマンス
バッチサイズの影響
シャーディングテーブルでは、シャーディング関数により行が複数のシャードに分散されるため、シャードごとの実効的なバッチサイズはステートメントレベルのバッチサイズより小さくなります。すべての行を 1 つの大規模ステートメントで送信することで、シャーディング関数が行を均等に分散し、シャードごとのバッチサイズを最大化できます。これにより、データノードのパフォーマンスが向上します。
BATCH_INSERT_POLICY=SPLIT の場合(DOP = 32、32 シャード)
| バッチサイズ(行) | 1 | 10 | 100 | 500 | 1,000 | 2,000 | 5,000 | 10,000 |
|---|---|---|---|---|---|---|---|---|
| スループット(行/秒) | 12,804 | 80,987 | 229,995 | 401,215 | 431,579 | 410,120 | 395,398 | 389,176 |
バッチサイズが 2,000 行以上になると、自動分割がトリガーされます。
1,000 行でスループットは約 430,000 行/秒に達し、非シャーディングテーブルのベースラインの約 2 倍となります。
BATCH_INSERT_POLICY=NONE の場合(DOP = 32、32 シャード)
| バッチサイズ(行) | 1,000 | 2,000 | 5,000 | 10,000 | 20,000 | 30,000 | 50,000 |
|---|---|---|---|---|---|---|---|
| スループット(行/秒) | 431,579 | 463,112 | 490,350 | 526,751 | 549,990 | 595,026 | 685,500 |
自動分割を無効にした場合、バッチサイズの増加に伴いスループットは継続的に向上し、50,000 行で約 680,000 行/秒に達します。
DOP の影響
バッチ挿入ワークロードは CPU バウンドではなく、IOPS バウンドです。ほとんどのオーバーヘッドはデータノードに発生するため、DOP はノード数およびノードスペックに合わせてチューニングする必要があります。最適な値を導出するための数式は存在せず、実際の環境でテストして最適値を特定してください。
4 ノードクラスター(32 シャード、バッチサイズ = 1,000)
| DOP(スレッド数) | 1 | 2 | 4 | 8 | 16 | 32 | 64 | 80 | 96 |
|---|---|---|---|---|---|---|---|---|---|
| スループット(行/秒) | 40,967 | 80,535 | 151,415 | 246,062 | 367,720 | 431,579 | 478,876 | 499,918 | 487,173 |
スループットは DOP 64–80 でピークに達し、約 500,000 行/秒となります。
ノード数によるスケーリング(バッチサイズ = 20,000)
| ノード数 | シャード | ピーク DOP | ピークスループット |
|---|---|---|---|
| 2(コンピュート 2 + データ 2) | 16 | 8 | 約 300,000 行/秒 |
| 3(コンピュート 3 + データ 3) | 24 | 12 | 約 450,000 行/秒 |
| 4(コンピュート 4 + データ 4) | 32 | 32 | 約 550,000 行/秒 |
ノードを追加すると、追加ノードごとに約 90%–100% の線形スケールアップが得られます。
ノードスペックによるスケーリング(バッチサイズ = 20,000)
| ノードスペック | ピーク DOP | ピークスループット |
|---|---|---|
| 4 コア、16 GB メモリ | 8 | 約 280,000 行/秒 |
| 8 コア、32 GB メモリ | 10 | 約 340,000 行/秒 |
| 16 コア、64 GB メモリ | 32 | 約 550,000 行/秒 |
ノードスペックをアップグレードすると、スペック階層ごとに約 50%–60% のスループット向上が得られます。ただし、ノードを追加する方が、ノードスペックをアップグレードするよりも高いスループット向上が得られます。
推奨事項
同時実行性とリソース効率のバランスを取る場合:
バッチサイズ:1,000 行
DOP:16–32
これは、4 ノード・32 シャードのクラスターにおいて、予測可能なリソース使用量で約 430,000 行/秒のスループットを実現します。
最大書き込みスループットを実現する場合:
バッチサイズ:
シャード数 × 100~シャード数 × 1,000(例:32 シャードのクラスターでは 20,000–50,000 行)ターゲットステートメントサイズ:2 MB–8 MB(最大:16 MB)
自動分割を無効化:ステートメントに
/*+TDDL:CMD_EXTRA(BATCH_INSERT_POLICY=NONE)*/を追加DOP は、ご使用のノード数およびノードスペックに基づいて設定(上記の表を参照)
書き込みスループットのスケーリングを行う場合:
ノードスペックのアップグレードよりも、ノードを追加することを推奨します。ノードの追加は、追加ノードごとに 90%–100% の線形向上を実現しますが、ノードスペックのアップグレードは 50%–60% の向上にとどまります。
バッチ挿入ワークロードは IOPS バウンドであり、CPU 使用率およびメモリは主なボトルネックではありません。
オンプレミスのファイルからデータをインポートする場合:
大量データのインポートおよびエクスポートに特化した Batch Tool を使用します。「Batch Tool を使用したデータのエクスポートおよびインポート」をご参照ください。