固定プランは、Hologres に特有の実行エンジン最適化機能です。本トピックでは、SQL ステートメントが固定プランの対象となるために必要な前提条件とパラメーター構成について説明します。
背景情報
固定プランは、Hologres に特有の実行エンジン最適化手法です。従来の SQL 実行では、オプティマイザー、コーディネーター、クエリエンジン、ストレージエンジンなど複数のコンポーネントが関与します。一方、固定プランでは、オプティマイザー、コーディネーター、およびクエリエンジンの一部をバイパスするショートカットパスを使用して処理オーバーヘッドを削減します。固定フロントエンドが直接固定クエリエンジンに接続することで、SQL 実行効率が大幅に向上します。この重要な最適化により、高スループットのリアルタイム書き込みおよび高同時実行クエリが可能になります。固定プランの詳細については、「プロダクトアーキテクチャ」をご参照ください。
Hologres では、以下のシナリオで固定プランがデフォルトで使用されます。
-
Flink を使用した Hologres へのリアルタイム書き込み。
-
DataWorks の Data Integration を使用した Hologres へのリアルタイム書き込み。
-
Holo Client を使用した Hologres への書き込み。
その他の書き込みシナリオでは、SQL ステートメントを構成して固定プランを使用できます。詳細については、以下のセクションをご参照ください。
これらのシナリオでは、対象となる SQL ステートメントに対して Hologres がデフォルトで固定プランを使用します。ただし、これらのシナリオ内のすべての SQL ステートメントが対象となるわけではありません。
関連 GUC パラメーター
-
GUC パラメーターリスト
以下のパラメーターは、固定プランの構成に使用されます。各パラメーターの値は on または off です。すべてのパラメーターは、Holo Client でデフォルトで有効になっており、セッションレベルで有効になります。
パラメーター
説明
デフォルト
変更履歴
hg_experimental_enable_fixed_dispatcher
インスタンスで固定プラン機能を有効にするかどうかを制御します。
単一行の
INSERT、UPDATE、DELETE、およびPrefixScan操作の固定プランをサポートします。on
該当なし。
hg_experimental_enable_fixed_dispatcher_for_multi_values
複数行の
INSERT操作で固定プランを使用するかどうかを制御します。説明原子性は保証されません。複数行の挿入操作において、成功した場合はすべての行が挿入されています。エラーが発生した場合、システムは部分的な挿入または完全な失敗を示す可能性のある単一のメッセージを返します。クライアントアプリケーションは、失敗した行をリトライする必要があります。
on
Hologres V1.3.35 以降では、この GUC パラメーターにより、複数行の
INSERT、UPDATE、およびDELETE操作で固定プランを使用できるようになりました。hg_experimental_enable_fixed_dispatcher_autofill_series
SERIAL型の列を含むテーブルへの書き込みで固定プランをサポートします。このパラメーターはセッションレベルで有効にすることを推奨します。on
Hologres V1.3.25 でデフォルト値が
onに変更されました。hg_experimental_enable_fixed_dispatcher_for_update
UPDATE操作で固定プランをサポートします。このパラメーターはセッションレベルで有効にすることを推奨します。off
Hologres V1.3.25 以降、
hg_experimental_enable_fixed_dispatcher_for_updateパラメーターは非推奨となりました。対象となる UPDATE ステートメントはデフォルトで固定プランを使用します。ただし、複数行を更新するには、set hg_experimental_enable_fixed_dispatcher_for_multi_values = onを構成する必要があります。hg_experimental_enable_fixed_dispatcher_for_delete
DELETE操作で固定プランをサポートします。このパラメーターはセッションレベルで有効にすることを推奨します。off
Hologres V1.3.25 以降、
hg_experimental_enable_fixed_dispatcher_for_deleteパラメーターは非推奨となりました。対象となる DELETE ステートメントはデフォルトで固定プランを使用します。ただし、複数行を削除するには、set hg_experimental_enable_fixed_dispatcher_for_multi_values = onを構成する必要があります。hg_experimental_enable_fixed_dispatcher_for_scan
PrefixScanクエリで固定プランをサポートします。説明PrefixScanクエリとは、複合プライマリキーを持つテーブルに対して、クエリ条件でプライマリキーの先頭列のみを指定するクエリです。現在、列指向テーブルに対するPrefixScanクエリの固定プランはサポートされていません。off
Hologres V1.3.35 以降を推奨します。
hg_experimental_enable_bhclient_cache_on_session
キャッシュモードを制御します。2 つのモードがあります。
-
on:
cached on sessionモードを使用します。 -
off:
cached on feモードを使用します。
説明以下に、
cached on sessionモードとcached on feモードを比較します。-
cached on session: 各セッションに独自のライターとリーダーがあります。このモードはセッションごとのスループットが高くなりますが、各テーブルに対する最初の操作前にライターとリーダーの初期化が必要なため、起動が遅くなります。 -
cached on fe: FE ノード上のすべてのセッションでライターとリーダーを共有します。セッション終了時にライターやリーダーはクローズされないため、起動時間がなくなります。
off
該当なし。
hg_experimental_disable_fixed_planner_conflict_pk_check
INSERT INTO <table_name> VALUES (...) ON CONFLICT(<column>)構文のがプライマリキー以外の列であることを許可するかどうかを制御します。 -
false: サポートされません。
-
true: サポートされます。
説明この GUC パラメーターが
trueに設定されている場合、プライマリキー以外の列を指定できます。ただし、INSERT ON CONFLICT ステートメントは、プライマリキーが重複しているかどうかに基づいてデータを処理します(あたかもON CONFLICT(pk)が指定されたかのように動作します)。
false
-
Hologres V1.3 ~ V2.1.28 では、
ON CONFLICT(<column>)で指定される列はプライマリキー列である必要があります。 -
このパラメーターは Hologres V2.1.29 以降の V2.1.x リリースでのみ利用可能です。
ON CONFLICT(<column>)の列がプライマリキー以外であってもよいかどうかを制御します。V3.0 以降ではこのパラメーターは削除され、構成は不要です。
-
-
GUC パラメーターの使用方法
-
GUC パラメーターの設定確認
SHOWコマンドを使用して、GUC パラメーターの設定を確認します。SHOW <GUC_name>;例:
-- インスタンスレベルで固定プラン機能が有効になっているかを確認します。 SHOW hg_experimental_enable_fixed_dispatcher; -
GUC パラメーターの設定
-
セッションレベルでの GUC パラメーター設定
SETコマンドを使用して、セッションレベルで GUC パラメーターを構成できます。この設定は現在のセッションにのみ適用され、セッション終了時に破棄されます。SQL ステートメントの前にこのコマンドを含めることを推奨します。SET <GUC_name> = <values>;GUC_name は GUC パラメーターの名前を、values はパラメーターの値を指定します。
例:
-- 複数行 INSERT ON CONFLICT ステートメントで固定プランを有効にします。 SET hg_experimental_enable_fixed_dispatcher_for_multi_values = on; -
データベースレベルでの GUC パラメーター設定
ALTER DATABASE ... SET ...コマンドを使用して、データベースレベルで GUC パラメーターを設定できます。この設定はデータベース全体に適用されます。現在のセッションに変更を反映させるには、再接続する必要があります。この設定は新しいデータベースには適用されないため、それぞれ手動で構成する必要があります。ALTER DATABASE <db_name> SET <GUC_name> = <values>;db_name はデータベース名、GUC_name は GUC パラメーターの名前、values はパラメーターの値を指定します。
例:
-- データベースレベルで固定プラン機能を有効にします。 ALTER DATABASE <db_name> SET hg_experimental_enable_fixed_dispatcher = on;
-
-
データ型要件
-
テーブルの列は、
MONEY型またはMONEY ARRAY型であってはなりません。 -
DML (
INSERT、UPDATE、およびDELETE) およびSELECT操作の列では、以下のデータ型がサポートされます。SELECTステートメントの場合、この要件はターゲット列とWHERE句の列の両方に適用されます。-
BOOLEAN(エイリアス:BOOL) -
SMALLINT -
INTEGER(エイリアス:INT、INT4) -
BIGINT(エイリアス:INT8) -
FLOAT(エイリアス:FLOAT4) -
DOUBLE PRECISION(エイリアス:FLOAT8) -
CHAR(n) -
VARCHAR(n)(Hologres V1.1.79 以降では、VARCHARで固定プランを使用できます。) -
BYTEA -
JSONおよびJSONB -
TEXT(エイリアス:VARCHAR) -
TIMESTAMP WITH TIME ZONE(エイリアス:TIMESTAMPTZ) -
DATE -
TIMESTAMP -
DECIMAL(エイリアス:NUMERIC) -
ROARINGBITMAP -
TIME(Hologres V2.2 以降でサポート) -
TIMETZ(Hologres V2.2 以降でサポート) -
配列型
-
boolean[] -
smallint[] -
int4[] -
int8[] -
float4[] -
float8[] -
char(n)[] -
varchar(n)[] -
text[]
-
-
挿入シナリオ
Hologres V3.2 以降では、プライマリキーを持つテーブルに固定プランを使用してデータを書き込む INSERT ステートメントで RETURNING 句を使用できます。
-
INSERT ステートメント
以下の INSERT ステートメントで固定プランを使用できます。
-- 単一行を書き込みます。 INSERT INTO TABLE(col1,col2,col3..) VALUES(?,?,?..) ON conflict xxx; -- 複数行を書き込みます。 INSERT INTO TABLE(col1,col2,col3..) VALUES(?,?,?..),(?,?,?..) ON conflict xxx;説明-
INSERT ステートメントを使用して内部テーブルにデータを書き込むことはできますが、外部テーブルには書き込めません。
-
INSERT ステートメントを使用してパーティションテーブルにデータを書き込むことができます。Hologres V1.3 以降では、親パーティションテーブルへの書き込みもサポートされています。
-
RETURNINGキーワードは、Hologres V3.2 以降でサポートされています。V3.2 より前のバージョンではサポートされていません。
-
-
単一行 INSERT ON CONFLICT
-
以下のシナリオがサポートされます。
-
ON CONFLICT句のない INSERT ステートメント。 -
ON CONFLICT DO NOTHING句を含む INSERT ステートメント。 -
ON CONFLICT DO UPDATE句を含む INSERT ステートメント。固定プランを使用するには、INSERT ステートメントで指定されたすべての非プライマリキー (非 PK) 列を更新する必要があります。プライマリキー (PK) 列を更新することは任意です。更新にはcol = excluded.col形式を使用する必要があります。Hologres V1.3 以降では、非 PK 列のサブセットを更新できますが、col = excluded.col形式は引き続き必要です。
-
-
例:
BEGIN; CREATE TABLE test_insert_oneline ( pk1 INT, pk2 INT, col1 INT, col2 INT, PRIMARY KEY (pk1, pk2) ); COMMIT; -- すべての非 PK 列を更新します。固定プランを使用できます。 INSERT INTO test_insert_oneline VALUES (1, 2, 3, 4) ON CONFLICT (pk1, pk2) DO UPDATE SET col1 = excluded.col1, col2 = excluded.col2; -- PK 列と非 PK 列のすべてを更新します。固定プランを使用できます。 INSERT INTO test_insert_oneline VALUES (1, 2, 3, 4) ON CONFLICT (pk1, pk2) DO UPDATE SET col1 = excluded.col1, col2 = excluded.col2, pk1 = excluded.pk1, pk2 = excluded.pk2; -- 固定プランでは、INSERT ステートメントで指定されたすべての非 PK 列を更新する必要があります。col2 が省略されているため、このステートメントは Hologres V1.3 以降でのみサポートされます。 INSERT INTO test_insert_oneline VALUES (1, 2, 3, 4) ON CONFLICT (pk1, pk2) DO UPDATE SET col1 = excluded.col1; -- 更新にリテラル値を使用しており、必要な 'col = excluded.col' 形式ではないため、固定プランはサポートされません。 INSERT INTO test_insert_oneline VALUES (1, 2, 3, 4) ON CONFLICT (pk1, pk2) DO UPDATE SET col1 = excluded.col1, col2 = 5;
-
-
複数行 INSERT ON CONFLICT
-
複数行 INSERT ON CONFLICT 操作では、以下の構文を使用します。
SET hg_experimental_enable_fixed_dispatcher_for_multi_values = ON; INSERT INTO TABLE (col1, col2, col3..) VALUES (?, ?, ?..), (?, ?, ?..) ON CONFLICT xxx;-
GUC パラメーター
hg_experimental_enable_fixed_dispatcher_for_multi_values = on;を設定する必要があります。Hologres V1.3.35 以降では、このパラメーターはデフォルトでonに設定されています。 -
これらの操作では原子性が保証されません。成功した操作ではすべての行が書き込まれます。エラーが発生した場合、一部またはすべての行が書き込まれていない可能性があります。
-
-
あるいは、複数行を書き込むために以下の構文を使用することもできます。
SET hg_experimental_enable_fixed_dispatcher_for_multi_values = ON; INSERT INTO TABLE SELECT unnest(ARRAY[TRUE, FALSE, TRUE]::bool[]), unnest(ARRAY[1, 2, 3]::int4[]), unnest(ARRAY[1.11, 2.222, 3]::float4[]) ON CONFLICT xxx;-
GUC パラメーター
hg_experimental_enable_fixed_dispatcher_for_multi_values=on;を設定する必要があります。 -
配列型の列にデータを書き込むことはできません。
-
unnest関数の配列は、対応する列の配列型に明示的にキャストする必要があります。
例:
BEGIN; CREATE TABLE test_insert_multiline ( pk1 int8, col1 float4, PRIMARY KEY (pk1) ); COMMIT; -- 固定プランがサポートされます。 SET hg_experimental_enable_fixed_dispatcher_for_multi_values = ON; INSERT INTO test_insert_multiline SELECT unnest(ARRAY[1, 2, 3]::int8[]), unnest(ARRAY[1.11, 2.222, 3]::float4[]) ON CONFLICT DO NOTHING; -- unnest 関数の ARRAY が明示的にキャストされていません。固定プランはサポートされません。 INSERT INTO test_insert_multiline SELECT unnest(ARRAY[1, 2, 3]), unnest(ARRAY[1.11, 2.222, 3]) ON CONFLICT DO NOTHING; -- 最初の列は int8 型であるため、配列は int8[] にキャストする必要があります。 -- この例では int4[] にキャストされているため、固定プランはサポートされません。 INSERT INTO test_insert_multiline SELECT unnest(ARRAY[1, 2, 3]::int4[]), unnest(ARRAY[1.11, 2.222, 3]::float4[]) ON CONFLICT DO NOTHING; -
-
-
部分更新シナリオ
Hologres では、プライマリキーを使用してテーブルの特定の列を更新できます。以下の条件を満たす場合、固定プランを部分更新にも使用できます。
-
INSERT リストの列数と順序が、UPDATE リストの列数と順序と一致していること。
-
更新に
col = excluded.col形式を使用していること。
-
-
条件付き UPSERT
同じプライマリキーを持つ行の上流データの順不同を処理するために、Hologres では HBase CheckAndPut 操作に類似した機能を提供しています。以下の条件を満たす場合、
INSERTまたはUPDATEステートメントに条件句を付けて固定プランを使用できます。-
この機能は単一行の挿入でサポートされています。複数行の挿入では、GUC パラメーター
set hg_experimental_enable_fixed_dispatcher_for_multi_values=on;を設定する必要があります。 -
WHERE句には非 PK 列が 1 つだけ含まれている必要があり、比較演算子は次のいずれかである必要があります:=, <>, >, >=, <, <=, IS NULL, または IS NOT NULL。この非 PK 列に対してcoalesce関数を使用できます。
例:
BEGIN; CREATE TABLE test_check_and_insert ( pk INT, col INT, scn INT, PRIMARY KEY (pk) ); COMMIT; -- 固定プランがサポートされます。 -- 既存の列値を定数と比較します。 INSERT INTO test_check_and_insert AS old VALUES (1, 1, 1) ON CONFLICT (pk) DO UPDATE SET col = excluded.col, scn = excluded.scn WHERE old.scn > 0; -- 既存の列値を挿入される新しい値と比較します。 INSERT INTO test_check_and_insert AS old VALUES (1, 1, 1) ON CONFLICT (pk) DO UPDATE SET col = excluded.col, scn = excluded.scn WHERE old.scn > excluded.scn; -- 既存の値が NULL の可能性がある場合は、coalesce を使用します。 INSERT INTO test_check_and_insert AS old VALUES (1, 1, 1) ON CONFLICT (pk) DO UPDATE SET col = excluded.col, scn = excluded.scn WHERE coalesce(old.scn, 3) > 2; INSERT INTO test_check_and_insert AS old VALUES (1, 1, 1) ON CONFLICT (pk) DO UPDATE SET col = excluded.col, scn = excluded.scn WHERE coalesce(old.scn, 3) > excluded.scn; -- 固定プランがサポートされます。 SET hg_experimental_enable_fixed_dispatcher_for_multi_values = ON; -- 既存の列値を定数と比較します。 INSERT INTO test_check_and_insert AS old VALUES (1, 1, 1), (2, 3, 4) ON CONFLICT (pk) DO UPDATE SET col = excluded.col, scn = excluded.scn WHERE old.scn > 3; -- unnest 構文もサポートされます。 INSERT INTO test_check_and_insert AS old SELECT unnest(ARRAY[5, 6, 7]::int[]), unnest(ARRAY[1, 1, 1]::int[]), unnest(ARRAY[1, 1, 1]::int[]) ON CONFLICT (pk) DO UPDATE SET col = excluded.col, scn = excluded.scn WHERE old.scn > 3; -
-
デフォルト列
以下の条件を満たす場合、デフォルト値を持つ列を含むテーブルへの書き込みで固定プランを使用できます。
-
この機能は単一行の挿入でサポートされています。複数行の挿入では、Hologres インスタンスが V1.1.36 以降である必要があります。それ以前のバージョンの場合は、アップグレードしてください。また、GUC パラメーター
set hg_experimental_enable_fixed_dispatcher_for_multi_values=on;を設定する必要があります。 -
Hologres V1.3 以降のバージョンでは、デフォルト列を持つテーブルに対する
Insert on conflict句で固定プランがサポートされています。それ以前のバージョンのインスタンスでは、デフォルト列を持つテーブルに対するInsert on conflict句では固定プランはサポートされていません。
例:
BEGIN; CREATE TABLE test_insert_default ( pk1 INT, col1 INT DEFAULT 99, PRIMARY KEY (pk1) ); COMMIT; -- 固定プランがサポートされます。 INSERT INTO test_insert_default (pk1) VALUES (1); -- これは Hologres V1.1.36 以降が必要です。 SET hg_experimental_enable_fixed_dispatcher_for_multi_values = ON; INSERT INTO test_insert_default (pk1) VALUES (1), (2), (3); -
-
シリアル列
以下の条件を満たす場合、自動インクリメントの SERIAL 列を持つテーブルへの単一行または複数行の書き込みで固定プランを使用できます。
-
GUC パラメーター
set hg_experimental_enable_fixed_dispatcher_autofill_series=on;を設定する必要があります。Hologres V1.3.25 以降では、このパラメーターのデフォルト値はonです。 -
複数行の挿入では、GUC パラメーター
set hg_experimental_enable_fixed_dispatcher_for_multi_values=on;も設定する必要があります。
例:
BEGIN; CREATE TABLE test_insert_serial ( pk1 INT, col1 SERIAL, PRIMARY KEY (pk1) ); COMMIT; -- 固定プランがサポートされます。 SET hg_experimental_enable_fixed_dispatcher_autofill_series = ON; INSERT INTO test_insert_serial (pk1) VALUES (1); -- 固定プランがサポートされます。 SET hg_experimental_enable_fixed_dispatcher_autofill_series = ON; SET hg_experimental_enable_fixed_dispatcher_for_multi_values = ON; INSERT INTO test_insert_serial (pk1) VALUES (1), (2), (3); -
更新シナリオ
-
UPDATE ステートメント
以下の句を含む
UPDATEステートメントで固定プランを使用できます。SET hg_experimental_enable_fixed_dispatcher_for_update = ON; UPDATE TABLE SET col1 = ?,col2 = ? WHERE pk1 = ? AND pk2 = ?; -
使用上の注意
UPDATEステートメントが以下の条件を満たす場合、固定プランを使用できます。-
内部テーブルおよび子パーティションテーブルを更新できますが、外部テーブルまたは親パーティションテーブルは更新できません。テーブルにはプライマリキー (PK) が必要です。
-
コマンド
SET hg_experimental_enable_fixed_dispatcher_for_update = ON;を実行する必要があります。Hologres V1.3.25 以降、このパラメーターは非推奨となりました。対象となるUPDATEステートメントは自動的に固定プランを使用します。ただし、複数行を一度に更新するには、コマンドSET hg_experimental_enable_fixed_dispatcher_for_multi_values = ON;を実行する必要があります。 -
SET句で指定された列は、プライマリキー列であってはなりません。 -
WHERE句にはすべてのプライマリキー列を指定する必要があります。Hologres V1.3 以降では、WHERE句の最後の条件を非プライマリキー列に設定でき、=, <>, >, >=, <, <=, IS NULL, および IS NOT NULLの比較演算子またはcoalesce関数を使用できます。 -
pk in (?,?,?) or pk = ANY(...)を使用して、1 つのステートメントで複数行を更新できます。たとえば、pk1 in (1,2) and pk2 = any('{3,4}') and pk3 = 5は次の 4 行を更新します:(1,3,5), (1,4,5), (2,3,5), および (2,4,5)。 -
WHERE句の各列には 1 つの条件しか設定できません。同一の条件は 1 つの条件として扱われます。
例:
BEGIN; CREATE TABLE test_update ( pk1 INT, pk2 INT, col1 INT, col2 INT, PRIMARY KEY (pk1, pk2) ); COMMIT; -- 固定プランがサポートされます。 SET hg_experimental_enable_fixed_dispatcher_for_update = ON; UPDATE test_update SET col1 = 1, col2 = 2 WHERE pk1 = 3 AND pk2 = 4; -- 固定プランがサポートされます。 SET hg_experimental_enable_fixed_dispatcher_for_update = ON; UPDATE test_update SET col1 = 1 WHERE pk1 = 3 AND pk2 = 4; -- 固定プランがサポートされます (Hologres V1.3+、非プライマリキー列を含む WHERE 句)。 SET hg_experimental_enable_fixed_dispatcher_for_update = ON; UPDATE test_update SET col1 = 1 WHERE pk1 = 3 AND pk2 = 4 AND col1 > 3; -- 固定プランがサポートされます (Hologres V1.3+、非プライマリキー列と coalesce を含む WHERE 句)。 SET hg_experimental_enable_fixed_dispatcher_for_update = ON; UPDATE test_update SET col1 = 1 WHERE pk1 = 3 AND pk2 = 4 AND coalesce(col1, 4) <> 1; -- 固定プランがサポートされます。 SET hg_experimental_enable_fixed_dispatcher_for_update = ON; UPDATE test_update SET col1 = 1, col2 = 2 WHERE pk1 IN (1, 2) AND pk2 = ANY ('{3,4}'); -- 固定プランがサポートされます (Hologres V1.3+、非プライマリキー列を含む WHERE 句)。 SET hg_experimental_enable_fixed_dispatcher_for_update = ON; UPDATE test_update SET col1 = 1 WHERE pk1 IN (1, 2) AND pk2 = ANY('{3,4}') AND col1 > 3; -- 固定プランはサポートされません (pk1 に複数の条件があります)。 UPDATE test_update SET col1 = 1, col2 = 2 WHERE pk1 = 3 AND pk1 = 4; -- 固定プランはサポートされません (pk1 に複数の条件があります)。 UPDATE test_update SET col1 = 1, col2 = 2 WHERE pk1 IN (1, 2) AND pk1 = 1; -- 固定プランがサポートされます (pk1 に複数の同一条件があります)。 SET hg_experimental_enable_fixed_dispatcher_for_update = ON; UPDATE test_update SET col1 = 1, col2 = 2 WHERE pk1 IN (1, 2) AND pk1 IN (1, 2) AND pk2 = 4; -
削除シナリオ
-
DELETE ステートメント
以下のステートメントは、
DELETE操作で固定プランを使用する方法を示しています。SET hg_experimental_enable_fixed_dispatcher_for_delete = ON; DELETE FROM TABLE WHERE pk1 = ? AND pk2 = ? AND pk3 = ?; -
使用上の注意
DELETE操作が以下の条件を満たす場合、固定プランを使用できます。-
操作の対象は内部テーブルまたは子テーブルである必要があり、外部テーブルまたは親パーティションテーブルであってはなりません。また、テーブルにはプライマリキー (PK) が必要です。
-
GUC パラメーター
hg_experimental_enable_fixed_dispatcher_for_delete=on;を設定する必要があります。Hologres V1.3.25 以降、このパラメーターは非推奨となりました。対象となるDELETEステートメントはデフォルトで固定プランを使用します。ただし、複数行を削除するには、コマンドset hg_experimental_enable_fixed_dispatcher_for_multi_values =onを実行する必要があります。 -
WHERE句にはすべてのプライマリキー列の条件を指定する必要があります。Hologres V1.3 以降では、WHERE句の最後の条件を非プライマリキーフィールドに適用でき、=, <>, >, >=, <, <=, IS NULL, および IS NOT NULLの比較演算子およびcoalesce関数をサポートします。 -
pk in (?,?,?) or pk = ANY()を使用して、1 回の操作で複数行を削除できます。たとえば、pk1 in (1,2) and pk2 = any('{3,4}') and pk3 = 5は次の 4 行を削除します:(1,3,5), (1,4,5), (2,3,5), および (2,4,5)。 -
WHERE句の各列には 1 つの条件しか設定できません。重複する条件は 1 つの条件として扱われます。
例:
BEGIN; CREATE TABLE test_delete ( pk1 INT, pk2 INT, col1 INT, col2 INT, PRIMARY KEY (pk1, pk2) ); COMMIT; -- この DELETE ステートメントは固定プランを使用します。その他のシナリオについては、UPDATE ステートメントの例をご参照ください。 SET hg_experimental_enable_fixed_dispatcher_for_delete = ON; DELETE FROM test_delete WHERE pk1 = 1 AND pk2 = 2; -
SELECT シナリオ
-
SELECT ステートメント
特定の句を含む SELECT ステートメントで固定プランがサポートされます。
SELECT col1, col2, col3, ... FROM TABLE WHERE pk1 = ? AND pk2 = ? AND pk3 = ?;-
クエリの対象は内部テーブルである必要があり、外部テーブルであってはなりません。
-
クエリの対象は子パーティションテーブルである必要があり、親パーティションテーブルであってはなりません。
-
テーブルにはプライマリキー (PK) が必要です。
-
-
ポイントクエリ (キー/値) シナリオ
固定プランを使用するポイントクエリには、以下の条件が適用されます。
-
WHERE句にはプライマリキーのすべての列のみを含める必要があります。 -
pk in (?,?,?) or pk = ANY()を使用して、一度に複数行をクエリできます。たとえば、pk1 in (1,2) and pk2 = any('{3,4}') and pk3 = 5は次の 4 行をクエリします:(1,3,5),(1,4,5),(2,3,5),(2,4,5)。 -
各列には 1 つの条件しか設定できません。重複する条件は 1 つとして扱われます。
-
LIMIT句が含まれる場合、その値は>0である必要があります。
例:
BEGIN; CREATE TABLE test_select ( pk1 INT, pk2 INT, col1 INT, col2 INT, PRIMARY KEY (pk1, pk2) ); CALL set_table_property ('test_select', 'orientation', 'row'); COMMIT; -- このクエリでは固定プランがサポートされます。 SELECT * FROM test_select WHERE pk1 = 1 AND pk2 = 2; -
-
PrefixScan シナリオ
-
PrefixScan 句
PrefixScan は、複合プライマリキーを持つテーブルに対するクエリに適用されます。これらのクエリは、プライマリキー列のプレフィックスに対して左端一致の原則を使用してフィルター処理を行います。以下のコードは、このような句の例を示しています。
SET hg_experimental_enable_fixed_dispatcher_for_scan = on; SELECT col1,col2,col3,... FROM TABLE WHERE pk1 = ? AND pk2 = ?; SELECT col1,col2,col3,... FROM TABLE WHERE pk1 = ? AND pk2 < ?;--Hologres V1.1.48 以降では、PK プレフィックスの最後の列に範囲条件を指定できます。 SELECT col1,col2,col3,... FROM TABLE WHERE pk1 = ? AND pk2 BETWEEN ? AND ?;--Hologres V1.1.48 以降では、PK プレフィックスの最後の列に範囲条件を指定できます。 -
PrefixScan の使用方法
PrefixScan を使用するには、以下の条件を満たす必要があります。
-
GUC パラメーター
hg_experimental_enable_fixed_dispatcher_for_scan=on;を設定し、Hologres インスタンスが V1.3.35 以降である必要があります。 -
テーブルには分散キーが必要であり、
WHERE句には分散キーのすべての列を含める必要があります。 -
WHERE句にはプライマリキーのプレフィックスのみを含めることができます。Hologres V1.1.48 以降では、プライマリキープレフィックスの最後の列に範囲条件 (上限と下限) を指定することもできます。説明プレフィックスの定義: プライマリキーが
(pk1,pk2,pk3)の場合、(pk1)および (pk1,pk2) はそのプレフィックスです。 -
行指向テーブルおよび行・列ハイブリッドテーブルのみが PrefixScan をサポートします。
-
各列には 1 つの条件しか設定できません。重複する条件は 1 つとして扱われます。
-
LIMIT句が含まれる場合、その値は > 0 である必要があります。
説明PrefixScan はすべての結果行を一度に返します。結果の合計バイトサイズが
hg_experimental_fixed_scan_bytesize_limitの値を超える場合、エラーが返されます:scan result size larger than fixed scan size limit。hg_experimental_fixed_scan_bytesize_limitパラメーターを、シナリオに適した値に構成できます。デフォルト値は 1,048,576 (1 MB) です。たとえば、テーブルのプライマリキーが
(pk1,pk2,pk3,pk4)で、分散キーがpk1,pk3であると仮定します。BEGIN; CREATE TABLE test_select_prefix ( pk1 INT, pk2 INT, pk3 INT, pk4 INT, PRIMARY KEY (pk1, pk2, pk3, pk4) ); CALL set_table_property ('test_select_prefix', 'orientation', 'row'); CALL set_table_property ('test_select_prefix', 'distribution_key', 'pk1,pk3'); COMMIT; -- 分散キーのすべての列を含んでいません。固定プランは使用できません。 SELECT * FROM test_select_prefix WHERE pk1 = ? AND pk2 = ?; -- プライマリキーのプレフィックスではありません。固定プランは使用できません。 SELECT * FROM test_select_prefix WHERE pk1 = ? AND pk3 = ?; -- 固定プランを使用できます。 SET hg_experimental_enable_fixed_dispatcher_for_scan = ON; SELECT * FROM test_select_prefix WHERE pk1 = ? AND pk2 = ? AND pk3 = ?;pk in (?,?,?)またはpk = ANY()を使用して、一度に複数行をクエリできます。以下の例を参照してください。pk1 IN (1,2) AND pk2 = 3 --2 つのキーグループをスキャンすることに相当します: (1,3) および (2,3)。 pk2 =any('{3,4}') AND pk1 IN (1,2) --4 つのキーグループをスキャンすることに相当します: (1,3), (1,4), (2,3), および (2,4)。 -
-
使用例
BEGIN; CREATE TABLE test_scan ( pk1 INT, pk2 INT, pk3 INT, col1 INT, PRIMARY KEY (pk1, pk2, pk3) ); CALL set_table_property ('test_scan', 'orientation', 'row'); CALL set_table_property ('test_scan', 'distribution_key', 'pk1,pk2'); COMMIT; INSERT INTO test_scan VALUES (1, 2, 3, 4); -- 固定プランがサポートされます。 SET hg_experimental_enable_fixed_dispatcher_for_scan = ON; SELECT * FROM test_scan WHERE pk1 = 1 AND pk2 = 2; -- 固定プランがサポートされます。 SET hg_experimental_enable_fixed_dispatcher_for_scan = ON; SELECT * FROM test_scan WHERE pk1 = 1 AND pk2 IN (2, 3); -- 固定プランがサポートされます。 SET hg_experimental_enable_fixed_dispatcher_for_scan = ON; SELECT * FROM test_scan WHERE pk1 = ANY ('{3,4}') AND pk2 IN (2, 3); -- 固定プランがサポートされます。PK の最後の列が範囲条件です。Hologres V1.1.48 以降が必要です。 SET hg_experimental_enable_fixed_dispatcher_for_scan = ON; SELECT * FROM test_scan WHERE pk1 = 1 AND pk2 = 1 AND pk3 > 1 AND pk3 < 4; -- 固定プランがサポートされます。PK の最後の列が範囲条件です。Hologres V1.1.48 以降が必要です。 SET hg_experimental_enable_fixed_dispatcher_for_scan = ON; SELECT * FROM test_scan WHERE pk1 = 1 AND pk2 = 1 AND pk3 BETWEEN 1 AND 4; -- 分散キーのすべての列を含んでいません。固定プランはサポートされません。 SELECT * FROM test_scan WHERE pk1 = 1; -- プライマリキープレフィックスと一致しません。固定プランはサポートされません。 SELECT * FROM test_scan WHERE pk2 = 2;
-
-
ページネーションシナリオ
Hologres V3.2 以降では、固定プランがページネーションを使用する PrefixScan クエリをサポートします。
説明-
デフォルトでは、PrefixScan の結果はプライマリキーの昇順でソートされます。以下の SQL 例では、
pk1およびpk2に対する PrefixScan は、pk3の昇順で結果を返します。 -
ソート順を指定するには、クラスタリングキー で列の順序を定義し、クエリで対応する GUC パラメーターを設定します。これにより、結果がクラスタリングキーに従ってソートされます。クラスタリングキーの列は、プライマリキーの列と同一である必要があります。以下の SQL 例では、結果を降順でソートするには、クラスタリングキーの最後の列を
pk3:descに設定します。
-
昇順
-- テーブルを作成します。 CREATE TABLE test_scan( pk1 INT, pk2 INT, pk3 INT, col1 INT, PRIMARY KEY(pk1, pk2, pk3) ) WITH ( orientation = 'row', distribution_key = 'pk1,pk2', clustering_key = 'pk1:asc,pk2:asc,pk3:asc' ); -- データを挿入します。 INSERT INTO test_scan VALUES (1,2,3,4),(1,2,5,6),(1,2,7,8); -- `offset + limit` がサポートされます。PrefixScan に基づき、このクエリは指定されたオフセットから指定された数の行を返します。 SET hg_experimental_enable_fixed_dispatcher_for_scan = on; -- デフォルトでは、結果は pk3 の昇順でソートされます。 SELECT * FROM test_scan WHERE pk1 = 1 AND pk2 = 2 OFFSET 1 limit 2; -
降順
-- テーブルを作成します。 CREATE TABLE test_scan( pk1 INT, pk2 INT, pk3 INT, col1 INT, PRIMARY KEY(pk1, pk2, pk3) ) WITH ( orientation = 'row', distribution_key = 'pk1,pk2', clustering_key = 'pk1:asc,pk2:asc,pk3:desc' ); -- データを挿入します。 INSERT INTO test_scan VALUES (1,2,3,4),(1,2,5,6),(1,2,7,8); -- 結果を pk3 の降順でソートするには、以下の 2 つの GUC パラメーターを有効にします。 SET hg_experimental_enable_fixed_dispatcher_for_scan = on; SET hg_experimental_enable_fixed_dispatcher_for_clustering_key_scan = on; SELECT * FROM test_scan WHERE pk1 = 1 AND pk2 = 2 OFFSET 1 limit 2;
-
COPY シナリオ
Hologres V1.3.17 以降、COPY ステートメントで固定プランを使用できます。この機能は Fixed Copy と呼ばれます。COPY と Fixed Copy の比較については、「バッチ書き込みのベストプラクティス」をご参照ください。
Fixed Copy パラメーターの詳細については、「COPY」をご参照ください。以下に例を示します。
COPY table_name (column0, column1, column2)
FROM
STDIN WITH (
format BINARY,
stream_mode TRUE,
on_conflict UPDATE);
COPY ステートメントで列を省略した場合の動作は次のとおりです。
-
COPYステートメントでテーブルの列のサブセットを指定すると、部分更新が実行されます。例:CREATE TABLE t0 ( id INT NOT NULL, name TEXT, age INT, PRIMARY KEY (id) ); COPY t0 (id, name) FROM STDIN WITH (stream_mode TRUE, on_conflict UPDATE); -- 上記の COPY ステートメントは、次の INSERT INTO ステートメントと同等です: INSERT INTO t0 (id, name) VALUES (?, ?) ON CONFLICT (id) DO UPDATE SET id = excluded.id, name = excluded.name; -
省略された列にデフォルト値がある場合、
COPYステートメントの動作は次のとおりです。CREATE TABLE t0 ( id INT NOT NULL, name TEXT, age INT DEFAULT 0, PRIMARY KEY (id) ); COPY t0 (id, name) FROM STDIN WITH (stream_mode TRUE, on_conflict UPDATE); -- 上記の COPY ステートメントは、次の INSERT INTO ステートメントと同等です: -- ID が存在しない場合、新しい行が挿入され、age 列はデフォルト値に設定されます。 -- ID がすでに存在する場合、行が更新され、age 列は変更されません。 INSERT INTO t0 (id, name, age) VALUES (?, ?, DEFAULT) ON CONFLICT (id) DO UPDATE SET id = excluded.id, name = excluded.name;
固定プランにおける式
Hologres V3.2 以降、固定プラン機能が SQL ステートメント内の式をサポートします。PostgreSQL における式の詳細については、「Expressions」をご参照ください。サポートされるシナリオは次のとおりです。
-
INSERT ステートメント:
-
VALUES 句
-
INSERT ON CONFLICT DO UPDATE 句
-
INSERT ON CONFLICT WHERE 句のフィルター条件
-
RETURNING 句
-
-
SELECT ステートメント:
SELECT リスト
制限事項
-
スカラー式および関数のみがサポートされます。集計関数、ウィンドウ関数、サブクエリはサポートされません。
-
INSERT ステートメントの場合、VALUES 句以外の句で使用される式および関数は、HQE でサポートされている必要があります。
-
SELECT ステートメントの場合、固定プランは定数引数を受け取る IMMUTABLE 式および関数のみをサポートします。
-
この機能を使用するには、以下のパラメーターを有効にする必要があります。
-- セッションレベルで有効にします SET hg_experimental_enable_fixed_plan_expression = on; -- データベースレベルで有効にします ALTER DATABASE <db_name> SET hg_experimental_enable_fixed_plan_expression = on;
例
-
INSERT ステートメントの 4 つのサポート対象句で式を使用
-- テーブルを作成します。 CREATE TABLE test_t ( id INT PRIMARY KEY, col INT, ts TIMESTAMP ) WITH ( orientation = 'row', distribution_key = 'id' ); -- GUC パラメーターを有効にします。 SET hg_experimental_enable_fixed_plan_expression = ON; -- VALUES 句で式を使用します。 INSERT INTO test_t VALUES (1, 1, now()); -- ON CONFLICT DO UPDATE 句で式を使用します。 INSERT INTO test_t AS old VALUES (1, 1, now()) ON CONFLICT (id) DO UPDATE SET col = excluded.col + old.col, ts = excluded.ts; -- ON CONFLICT WHERE 句で式を使用します。 INSERT INTO test_t AS old VALUES (1, 1, now()) ON CONFLICT (id) DO UPDATE SET col = excluded.col + old.col, ts = excluded.ts WHERE excluded.ts > old.ts; -- RETURNING 句で式を使用します。 INSERT INTO test_t AS old VALUES (1, 1, now()) ON CONFLICT (id) DO UPDATE SET col = excluded.col + old.col, ts = excluded.ts WHERE excluded.ts > old.ts RETURNING 2 * col, ts; -
SELECT ステートメントの SELECT リストで式を使用
-
完全なプライマリキーを使用したポイントクエリ: この例では、JSONB 列からキーの値を抽出します。
-- テーブルを作成します。 CREATE TABLE test_t ( id int PRIMARY KEY, ts TIMESTAMP NOT NULL, col JSONB ) WITH ( orientation = 'row', distribution_key = 'id' ); -- SELECT リストで式を使用します。JSONB 演算子がサポートされます。 SELECT (col ->> 'b')::int + (col ->> 'a')::int, date_trunc('day', ts) FROM test_t WHERE id = 1; -
プライマリキープレフィックスを使用した PrefixScan。
-- テーブルを作成します。 CREATE TABLE test_t ( id INT, ts TIMESTAMP NOT NULL, col JSONB, PRIMARY KEY (id, ts) ) WITH ( orientation = 'row', distribution_key = 'id' ); -- GUC パラメーターを有効にします。 SET hg_experimental_enable_fixed_dispatcher_for_scan = TRUE; -- SELECT リストで式を使用します。 SELECT (col ->> 'b')::int + (col ->> 'a')::int, date_trunc('day', ts) FROM test_t WHERE id = 1;
-
-
非 IMMUTABLE 関数または定数引数を受け取らない関数を含む SELECT ステートメントは、固定プランによって最適化できません。
-- テーブルを作成します。 CREATE TABLE test_t ( id INT PRIMARY KEY, ts TIMESTAMP NOT NULL, col JSONB ) WITH ( orientation = 'row', distribution_key = 'id' ); -- random() 関数は immutable ではなく、固定プランではサポートされていません。 SELECT id + random() FROM test_t WHERE id = 1; -- toString 関数は定数引数を受け取らず、固定プランではサポートされていません。 SELECT toString (id) FROM test_t WHERE id = 1;
固定プランの検証
-
コンソールでは、固定プランを使用して実行された
INSERT、UPDATE、およびDELETEステートメントが、リアルタイムインポート (RPS) パネルに SDK タイプとして表示されます。これらのリアルタイム書き込み操作では、データ更新効率を向上させるために固定プランを使用することを推奨します。
-
SQL 実行計画を表示するには、
EXPLAINステートメントを実行します。返された実行計画にFixedXXXNodeが含まれている場合、固定プランがトリガーされています (下図参照)。実行計画にFixedXXXNodeが含まれていない場合は、前述のセクションで説明されているサポート条件を確認し、ステートメントが要件を満たしているか検証してください。
パフォーマンスチューニング
固定プランを有効にしてもなおパフォーマンスをチューニングする必要がある場合は、以下の方法を使用できます。
-
実行計画を分析してパフォーマンスボトルネックを特定します。
EXPLAINを SQL ステートメントに対して実行し、各ステージで消費された時間を確認してボトルネックを特定します。 -
Hologres V1.1.49 以降では、固定プランを使用するポイントクエリが最適化され、大規模なシナリオでスループットが 30% 以上向上しています。この改善の恩恵を受けるには、インスタンスを V1.1.49 以降のバージョンにアップグレードしてください。
-
クライアント側でバッチ処理を行い、バッチサイズを 512 または 512 の倍数にしてください。Holo Client はバッチ処理を自動的に処理します。
よくある質問
-
症状: Hologres に接続しようとした際に、次のエラーが発生します:
role/database does not exist.-
原因: 指定されたユーザーまたはデータベースが存在しません。
-
解決策: 接続情報を確認し、ユーザー名とデータベース名が正しいことを確認してください。
Hologres コンソール にログインします。対象のインスタンスを見つけ、Actions 列の Manage をクリックします。Database Management をクリックします。その後、Users ページでユーザー名を、Database Authorization ページでデータベース名を確認できます。
-
-
症状: データ書き込み操作中に、次のエラーが発生します:
the requested table name: xxx (id: xx, version: xx) mismatches the version of the table (id: xx, version: xx) from server.-
原因: データ書き込み操作中にテーブルメタデータが変更され (例: 列の追加)、テーブルバージョンが変更されました。
-
解決策: 接続を再確立してください。これにより、固定プランが新しいテーブルメタデータを取得して書き込み操作を完了します。
-