挿入または更新のパフォーマンスが期待値を下回る場合、まず Hologres コンソールで CPU 使用率 メトリクスを確認します。CPU 使用率が低い場合は、上流のボトルネック (データ読み取りの遅延) を示しています。CPU 使用率が高い場合 (常に 100%) は、Hologres 自体がボトルネックとなっています。このトピックでは、両方のケースの診断と解決方法について説明します。
仕組み
Hologres のすべての SQL ステートメントは、次の 2 つの実行パスのいずれかに従います。
-
標準パス (HQE/PQE) — クエリオプティマイザ (QO) とクエリエンジン (QE) を経由します。書き込み操作は テーブルロック を取得するため、同時実行される
INSERT、UPDATE、DELETEステートメントは互いに待機する必要があるため、負荷がかかると高いレイテンシが発生します。HQE (Hologres Query Engine) はほとんどの書き込み操作を処理し、PQE (PostgreSQL Query Engine) は互換性シナリオを処理します。 -
Fixed Plan パス (FixedQE) — シンプルなポイント書き込みの場合、QO と QE をバイパスします。テーブルロックの代わりに 行ロック を使用するため、書き込みの同時実行性とスループットが大幅に向上します。

この区別を理解することで、書き込みパフォーマンスに関する問題のほとんどを説明できます。また、Fixed Plan を有効にすることが最も影響力の高い最適化である理由も明らかになります。
パフォーマンスのベースライン
チューニングを行う前に、テーブル構成におけるパフォーマンスの上限を把握してください。
ストレージ形式別 (全列の書き込み/更新):
行指向 > 列指向 > 行列ハイブリッド
ストレージ形式別 (部分列の書き込み/更新):
行指向 > 行列ハイブリッド > 列指向
列指向テーブルの書き込みモード別:
シンクテーブルにプライマリキーがない場合、パフォーマンスが最も高くなります。シンクテーブルにプライマリキーがある場合、パフォーマンスは次のようにランク付けされます。
InsertOrIgnore > InsertOrReplace >= InsertOrUpdate (全列) > InsertOrUpdate (部分列)
行指向テーブルの書き込みモード別:
InsertOrReplace = InsertOrUpdate (全列) >= InsertOrUpdate (部分列) >= InsertOrIgnore
Binlog が有効なテーブルの場合:
行指向 > 行列ハイブリッド > 列指向
書き込みモード
|
書き込みモード |
動作 |
プライマリキーが必要 |
|
|
追加のみ。重複行のチェックは行われません。 |
いいえ |
|
|
プライマリキーの競合が発生した場合、受信したレコードは破棄されます。 |
はい |
|
|
プライマリキーの競合が発生した場合、既存の行が置き換えられます。書き込みで指定されなかった列は NULL に設定されます。 |
はい |
|
|
プライマリキーの競合が発生した場合、指定された列のみが更新されます。書き込みで指定されなかった列は既存の値を保持します。 |
はい |
書き込みモードの選択:
-
プライマリキーがない追加専用パイプラインには、
Insertを使用します。 -
重複排除が上流で処理され、プライマリキーテーブルで最高の書き込みスループットを実現したい場合は、
InsertOrIgnoreを使用します。 -
全行の置き換えが必要で、指定されなかった列が NULL に設定されても問題ない場合は、
InsertOrReplaceを使用します。 -
部分列の更新には
InsertOrUpdateを使用します。ただし、エンジンが書き込み前に既存の行を検索する必要があるため、パフォーマンスのトレードオフが発生します。
ボトルネックの特定
Hologres コンソールで CPU 使用率を確認します。
|
CPU 使用率 |
解釈 |
次のステップ |
|
低 |
Hologres リソースが十分に活用されていません。ボトルネックは上流にあります。 |
上流のソースでデータ読み取りが遅くなっていないか確認してください。 |
|
高 (常に 100% 付近) |
Hologres がリソースのボトルネックに達しています。 |
このトピックのチューニング方法を適用してください。 |
クエリと書き込みが同時に実行される場合、クエリによって CPU 使用率が高くなり、書き込みパフォーマンスに影響を与える可能性があります。スロークエリログを確認して、同時実行クエリがリソースを消費していないかを確認してください。消費している場合は、読み書き分離 を使用した高可用性 (HA) デプロイの構成を検討してください。
すべてのチューニング方法を試しても書き込みパフォーマンスが要件を満たさない場合は、Hologres インスタンスをスケールしてください。
Fixed Plan の有効化
Fixed Plan は、書き込みパフォーマンスに最も大きな影響を与える最適化です。他の方法を試す前に、これを有効にしてください。
書き込みが Fixed Plan を使用しているかどうかの確認
Hologres コンソールで、次の RPS メトリクスを確認します。
-
[QE DML RPS] — 標準の HQE/PQE パスを経由する書き込み (テーブルロック、高レイテンシ)。
-
[FixedQE DML RPS] — Fixed Plan を使用する書き込み (行ロック、高い同時実行性)。

Fixed Plan を使用していない書き込み操作を見つけるには、スロークエリログにクエリを実行します。
-- 過去 3 時間に Fixed Plan を使用しなかった INSERT、UPDATE、DELETE 操作を検索
SELECT *
FROM hologres.hg_query_log
WHERE query_start >= now() - interval '3 h'
AND command_tag IN ('INSERT', 'UPDATE', 'DELETE')
AND ARRAY['HQE'] && engine_type
ORDER BY query_start DESC
LIMIT 500;
Fixed Plan が使用されないシナリオ
次のいずれかの条件に一致する SQL ステートメントは、HQE パスにフォールバックします。
-
複数行の
INSERT ON CONFLICT構文:INSERT INTO test_upsert(pk1, pk2, col1, col2) VALUES (1, 2, 5, 6), (2, 3, 7, 8) ON CONFLICT (pk1, pk2) DO UPDATE SET col1 = excluded.col1, col2 = excluded.col2; -
Hologres テーブルの列が挿入されたデータの列と一致しない部分更新の
INSERT ON CONFLICT。 -
Hologres テーブルには、
SERIAL型の列が含まれています。 -
Hologres テーブルには
Defaultプロパティが設定されています。 -
主キーに基づく
UPDATEまたはDELETE(例:UPDATE table SET col1 = ?, col2 = ? WHERE pk1 = ? AND pk2 = ?)。 -
Fixed Plan でサポートされていないデータ型。
これらのシナリオで Fixed Plan を有効にする
GUC パラメーターを使用して、Fixed Plan の適用範囲を拡張します。これらをデータベースレベルで設定します。
|
シナリオ |
GUC パラメーター |
備考 |
|
複数行の |
|
データベースレベルで設定します。 |
|
|
|
Hologres V1.3.25 以降では、デフォルトで |
|
|
Hologres V1.3 以降では GUC は不要です。 |
V1.3 以降では、 |
|
プライマリキーに基づく |
|
Hologres V1.3.25 以降では、デフォルトで |
|
|
|
Hologres V1.3.25 以降では、デフォルトは |
詳細については、「固定プランによる SQL 実行の高速化」をご参照ください。
書き込みで Fixed Plan が使用されると、[FixedQE DML RPS] メトリックでカウントされ、スロークエリログの engine_type フィールドに FixedQE と表示されます。

Fixed Plan が有効になっているが書き込みが依然として遅い
書き込みがすでに Fixed Plan を使用しているがレイテンシが依然として高い場合、最も一般的な原因は、同じテーブルに対する HQE と FixedQE の書き込みが混在していることです。HQE 操作はテーブルロックを保持するため、FixedQE 書き込みをブロックします。確認するには、次のクエリを実行します。
-- 過去 3 時間に特定のテーブルに対する HQE 操作を検索
SELECT *
FROM hologres.hg_query_log
WHERE query_start >= now() - interval '3 h'
AND command_tag IN ('INSERT', 'UPDATE', 'DELETE')
AND ARRAY['HQE'] && engine_type
AND table_write = '<table_name>'
ORDER BY query_start DESC
LIMIT 500;
すべての HQE 操作を FixedQE 互換のステートメントに書き換えてください。HoloWeb の「クエリインサイトの取得」を使用すると、HQE ロックが Fixed Plan 書き込みをブロックしているかどうかを迅速に特定できます。
すべての書き込みがすでに FixedQE 書き込みであり、レイテンシが依然として高い場合は、CPU 使用率を確認してください。CPU 使用率が常に高い場合は、インスタンスのリソースボトルネックを示しています。スケールアウトを検討してください。
基本的なチューニング方法
VPC 接続の使用
パブリックネットワークではなく、Virtual Private Cloud (VPC) 接続を使用してください。パブリックネットワークにはトラフィック制限があり、VPC よりもレイテンシが高くなります。これは、Java Database Connectivity (JDBC) または psql 経由でアプリケーションから接続する場合に特に当てはまります。
Hologres がサポートするネットワークタイプと選択のガイダンスについては、「ネットワーク構成」をご参照ください。
列指向テーブルでの Binlog の有効化を回避
Binlog は、すべての INSERT、UPDATE、DELETE を全行レベルで記録します。列指向テーブルの場合、全行の変更を記録するには、行全体を読み取るためのポイントクエリが必要です。これは、行指向テーブルよりもリソースを多く消費します。Binlog が必要な場合は、行指向テーブルを使用してください。
同じテーブルへのリアルタイム書き込みとバッチ書き込みの同時実行を回避
バッチ書き込み (例:MaxCompute から Hologres) はテーブルロックを使用します。ストリーム書き込み (例:Flink または DataWorks Data Integration) は通常、Fixed Plan を介して行ロックを使用します。両方が同じテーブルに対して同時に実行されると、バッチ書き込みのテーブルロックが、解放されるまですべてのリアルタイム書き込みをブロックします。これらのワークロードを分離してください。バッチ書き込みをメンテナンスウィンドウで実行するか、異なるテーブルに書き込みます。
INSERT OVERWRITE を使用したパーティションデータの置き換え
パーティション内のすべてのデータを置換またはクリアする必要がある場合は、DELETE の後に INSERT を実行するのではなく、INSERT OVERWRITE を使用してください。
INSERT OVERWRITE は、ファイルポインターをスワップすることでパーティションデータを置き換えるメタデータレベルの操作であり、迅速に実行され、動的プルーニングロジックをトリガーしません。対照的に、DELETE ステートメントでは、エンジンが行を特定して削除するためにパーティション内のすべてのデータファイルをスキャンする必要があるため、大きな I/O および CPU オーバーヘッドが発生します。DELETE + INSERT での書き込みパフォーマンスは、INSERT OVERWRITE よりも大幅に低くなります。
スケジューリングタスクを使用してパーティションテーブルに書き込む場合、INSERT OVERWRITE 文でスケジューリングパラメータを使用し、対象パーティションを直接指定します。削除および再挿入するデータを決定するためにサブクエリを使用することは避けてください。
-- 推奨:スケジューリングパラメーターを使用した INSERT OVERWRITE
INSERT OVERWRITE hologres_table PARTITION(ds='${bizdate}')
SELECT col1, col2, col3
FROM source_table
WHERE ds = '${bizdate}';
-- 非推奨:DELETE + INSERT
DELETE FROM hologres_table WHERE ds = '${bizdate}';
INSERT INTO hologres_table
SELECT col1, col2, col3
FROM source_table
WHERE ds = '${bizdate}';
Holo Client と JDBC 書き込みのチューニング
バッチ書き込み
バッチ書き込みを使用すると、単一レコードの書き込みよりも大幅に高いスループットが得られます。
-
Holo Client は自動的にデータをバッチ処理します。デフォルト設定を使用してください。
-
JDBC — 接続文字列に
reWriteBatchedInserts=trueを追加:jdbc:postgresql://{ENDPOINT}:{PORT}/{DBNAME}?ApplicationName={APPLICATION_NAME}&reWriteBatchedInserts=true
次の例は、バッチ処理の動作を示しています。
-- 2 つの個別の挿入 (低スループット)
INSERT INTO data_t VALUES (1, 2, 3);
INSERT INTO data_t VALUES (2, 3, 4);
-- バッチ挿入 (高スループット)
INSERT INTO data_t VALUES (1, 2, 3), (4, 5, 6);
-- または、unnest を使用
INSERT INTO data_t
SELECT unnest(ARRAY[1, 4]::int[]), unnest(ARRAY[2, 5]::int[]), unnest(ARRAY[3, 6]::int[]);
詳細については、「Holo Client」および「JDBC」をご参照ください。
プリペアドステートメントモードの使用
Hologres は PostgreSQL 拡張プロトコルとプリペアドステートメントモードをサポートしています。これにより、SQL コンパイル結果がサーバー上にキャッシュされ、書き込みごとにフロントエンド (FE) と QO による繰り返し解析のオーバーヘッドが排除されます。特に高頻度書き込みに有益です。
JDBC と Holo Client でプリペアドステートメントモードを有効にする方法については、「JDBC」をご参照ください。
Flink 書き込みのチューニング
テーブルタイプの要件
Binlog ソーステーブル:
-
Flink が Hologres Binlog を消費する際にサポートするデータ型は限られています。 スキーマにサポートされていない型 (たとえば
SMALLINTなど) が存在する場合、そのフィールドを消費しなくてもジョブが失敗することがあります。 Ververica Runtime (VVR) 6.0.3 以降では、Binlog の消費に JDBC モードを使用してください。このモードは、より多くのデータ型をサポートしています。 -
Binlog が有効なソースには行指向テーブルを使用してください。列指向テーブルで Binlog を有効にすると、より多くのリソースを消費し、書き込みパフォーマンスが低下します。
ディメンションテーブル:
-
行指向または行列ハイブリッドテーブルを使用してください。列指向テーブルは、ポイントクエリシナリオで高いオーバーヘッドがあります。
-
プライマリキーを設定してください。パフォーマンスを向上させるために、プライマリキーをクラスタリングキーとして構成してください。
-
ディメンションテーブルの主キーは、Flink
JOIN ON句で使用されるフィールドと完全に同一である必要があります。
シンクテーブル:
-
ワイドテーブルマージまたは部分更新の場合、Hologres テーブルにはプライマリーキーが必要です。各シンクテーブルは、プライマリーキーフィールドを宣言して書き込み、
InsertOrUpdate書き込みモードを使用し、リトラクションメッセージがDELETEリクエストを生成しないようにignoredelete = trueを設定する必要があります。 -
ワイドテーブルマージシナリオの列指向テーブルの場合、高 RPS (Records Per Second) で CPU 使用率を削減するために、テーブルフィールドのディクショナリエンコーディングを無効にしてください。
-
プライマリーキーがあるテーブルに
segment_keyを設定します。書き込み時間と強い相関関係があるタイムスタンプまたは日付フィールドを使用すると、書き込みや更新の際にエンジンが対象のデータファイルを迅速に特定するのに役立ちます。
推奨される Flink コネクタの設定
Hologres コネクタオプションのデフォルト値は、ほとんどのシナリオに適しています。次の問題が発生した場合に調整してください。
Binlog 消費の高レイテンシ:
デフォルトのバッチ読み取りサイズ (binlogBatchReadSize) は 100 行です。各行が小さい場合は、この値を大きくすると、消費レイテンシーを削減できます。
ディメンションテーブルのポイントクエリパフォーマンスの低下:
-
async = trueに設定すると非同期モードが有効になり、複数のリクエストを同時に処理して、連続するリクエスト間のブロッキングを排除します。なお、非同期モードでは厳密なリクエスト順序は保証されません。 -
大規模で更新頻度の低いディメンションテーブルの場合は、
cache = 'LRU'を設定して LRU キャッシュを有効にします。デフォルトのcacheSizeは 10,000 行 (控えめな値) です。実際のテーブルサイズとアクセスパターンに基づいて値を大きくしてください。
多数の Flink ジョブによる接続枯渇:
connectionPoolName パラメーターを使用します。 同じ TaskManager 内で同じ接続プール名を持つテーブルは、接続を共有します。
ジョブ開発の推奨事項
保守性と移植性のために、DataStream よりも Flink SQL を優先してください。
Flink SQL > Flink DataStream (コネクタ) > Flink DataStream (holo-client) > Flink DataStream (JDBC)
DataStream ジョブの場合は、生の JDBC ではなく、Hologres DataStream コネクタ または Holo Client を使用してください。
Flink 書き込みの遅延の診断
Flink での書き込みの遅延は、Hologres シンクではなく、ジョブの前段階のボトルネックが原因である可能性があります。ノードのバックプレッシャーを確認してください。ソースまたは計算ノードでバックプレッシャーが発生している場合、Hologres シンクに到達するデータはすでに遅延しています。まず上流の Flink ステップを最適化してください。
Hologres の CPU 使用率が常に 100% に近く、書き込みレイテンシが高い場合、ボトルネックは Hologres 側にあります。
一般的な Flink エラーと解決策については、「Blink と Flink の FAQ と診断」をご参照ください。
DataWorks Data Integration 書き込みのチューニング
接続と同時実行の設定
ウィザードモードでは、各同時実行スレッドは 3 つの接続を使用します。コードエディタモードでは、次を構成します。
-
maxConnectionCount— タスクの合計接続数。 -
insertThreadCount— 同時実行スレッドあたりの接続数。
ほとんどの場合、デフォルトの同時実行と接続設定で良好なパフォーマンスが得られます。リソース競合が発生した場合にのみ調整してください。
専用リソースグループのサイジング
ほとんどのデータ統合ジョブには専用リソースグループが必要です。リソースグループの仕様により、タスクのパフォーマンスの上限が設定されます。最適なスループットを得るには、リソースグループ内の CPU コアごとに 1 つの同時実行スレッドを割り当ててください。
リソースグループがタスクの同時実行性に対して小さすぎる場合、JVM メモリエラーが発生する可能性があります。リソースグループの帯域幅が飽和している場合は、タスクを小さなタスクに分割し、複数のリソースグループに分散してください。リソースグループの仕様とメトリクスについては、「パフォーマンスメトリクス」をご参照ください。
ボトルネックが上流か Hologres かを診断
-
読み取り側の待機時間が書き込み側の待機時間よりも長い場合、ボトルネックは上流のデータソースにあります。
-
Hologres の CPU 使用率が常に高く、書き込みレイテンシが上昇している場合、ボトルネックは Hologres 側にあります。
CPU 使用率が高い状態での DataX 書き込みの遅延
DataX 書き込みが遅く、Hologres インスタンスの監視で CPU 使用率が高いレベル (例:一部のワーカーノードが 100% に達する) を維持している場合、CPU リソースの飽和により、受信した書き込みリクエストがキューに入るか、処理遅延が発生しています。
この問題を解決するには、次の手順を実行します。
-
書き込みが Fixed Plan を使用しているかどうかを確認します。 Hologres コンソールで RPS メトリクスを確認します。書き込みが [FixedQE DML RPS] ではなく [QE DML RPS] (HQE パス) に表示される場合、Fixed Plan を使用していません。GUC パラメーターを構成するか、SQL ステートメントを書き換えて Fixed Plan を有効にしてください。詳細については、このトピックの「Fixed Plan の有効化」セクションをご参照ください。
-
Fixed Plan がすでに有効になっているが CPU 使用率が常に高い場合、 インスタンスがリソース容量に達しています。Hologres インスタンスをスケールして、より多くのコンピューティングリソースを追加してください。
高度なチューニング
これらの方法は、データ分散とテーブル構成によって引き起こされるパフォーマンスの問題に対処します。Fixed Plan を有効にし、基本的なチューニング方法を使用した後に適用してください。
データスキュー
データがスキューしているか、分散キーが不適切に設定されている場合、Hologres インスタンス内のコンピューティングリソースが不均衡になります。一部のシャードが他のシャードよりもはるかに多くの作業を行います。データスキューを確認して解決するには、「ワークロードスキューの検出と処理」をご参照ください。
不適切なセグメントキー
セグメントキーは、Hologres がデータを基盤となるストレージファイルにパーティション分割する方法を制御します。書き込みと更新中、Hologres はセグメントキーを使用して既存の行を特定します。セグメントキーが欠落しているか、関連のないフィールドに設定されているか、セグメントキーフィールドのデータが書き込み時刻と相関関係がない (例:順序が乱れて到着する) 場合、すべての書き込みで多数のファイルをスキャンする必要があり、ワークロードが書き込み中心であっても、大量の I/O と CPU を消費します。
症状:コンソールの IO スループットメトリクスで、主に書き込みワークロード中に高い読み取り値が表示されます。
修正: タイムスタンプまたは日付フィールドをセグメントキーとして使用してください。このフィールドのデータは、書き込み時刻と強い相関関係を持つ必要があります。ほぼ時系列で到着する値が最良の結果をもたらします。
行指向テーブルでの不適切なクラスタリングキー
プライマリキーを持つ行指向テーブルの場合、Hologres は書き込みまたは更新中に既存の行を検索するために、プライマリキーインデックスとクラスタリングキーインデックスの両方を使用します。クラスタリングキーがプライマリキーと異なる場合、各書き込みは 1 回ではなく 2 回のインデックス検索を実行するため、レイテンシが増加します。
行指向テーブルでは、クラスタリングキーとプライマリキーを同一に保ってください。
列指向テーブルでは、クラスタリングキーはクエリパフォーマンスに影響しますが、書き込みパフォーマンスには影響しません。書き込み最適化のための変更は必要ありません。