Fixed Plan は、Hologres 実行エンジン独自の最適化メソッドです。このトピックでは、SQL ステートメントで Fixed Plan を使用するために必要な条件とパラメーター設定について説明します。
背景情報
Fixed Plan は、Hologres 実行エンジン独自の最適化メソッドです。従来の SQL 実行は、オプティマイザー、コーディネーター、クエリエジン、ストレージエンジンなど、複数のコンポーネントを通過します。Fixed Plan はショートカットパスを使用して SQL 実行を最適化し、オプティマイザー、コーディネーター、およびクエリエジンの一部のオーバーヘッドをバイパスします。Fixed Frontend は Fixed Query Engine に直接接続します。これにより、SQL 実行効率が大幅に向上し、高スループットのリアルタイム書き込みや高同時実行性クエリにとって重要な最適化となります。Fixed Plan の詳細については、「サービスアーキテクチャ」をご参照ください。
Hologres では、以下のシナリオでデフォルトで Fixed Plan が使用されます。
Flink から Hologres へのリアルタイムデータ書き込み。
DataWorks のデータ統合から Hologres へのリアルタイムデータ書き込み。
Holo Client を使用した Hologres へのデータ書き込み。
その他の書き込みシナリオでは、Fixed Plan を使用するように SQL ステートメントを設定する必要があります。詳細については、以降のセクションをご参照ください。
これらのシナリオでは SQL ステートメントはデフォルトで Fixed Plan を使用しますが、すべてのステートメントが必要な条件を満たすわけではありません。
関連 GUC パラメーター
GUC リスト
以下の Grand Unified Configuration (GUC) パラメーターは Fixed Plan で使用されます。各パラメーターの値は on または off に設定できます。すべてのパラメーターは Holo Client でデフォルトで有効になっており、セッションレベルで有効になります。
GUC 名
シナリオ
デフォルト値
GUC 変更履歴
hg_experimental_enable_fixed_dispatcher
インスタンスで Fixed Plan が有効になっているかどうかを確認します。
データの書き込み、更新、削除、クエリを行うための単一行の INSERT、UPDATE、DELETE、および PrefixScan 操作の Fixed Plan をサポートします。
on
該当なし。
hg_experimental_enable_fixed_dispatcher_for_multi_values
複数行の INSERT 操作に対する Fixed Plan の書き込みを制御します。
説明原子性は保証されません。一度に複数のレコードを書き込む際に、エラーが報告されなければ、すべてのレコードが正常に書き込まれます。1 つのレコードでエラーが報告された場合、すべてのレコードの書き込みが失敗したか、一部が書き込まれて一部が書き込まれなかった可能性があります。失敗したレコードのエラーは、リトライのためにクライアントアプリケーションに送信されます。
on
Hologres V1.3.35 以降、この GUC は複数行の Insert、Update、Delete 操作の Fixed Plan をサポートします。
hg_experimental_enable_fixed_dispatcher_autofill_series
Serial 型の列を含むテーブルへの Fixed Plan 書き込みをサポートします。クライアント側でセッションレベルでこのパラメーターを有効にすることを推奨します。
off
Hologres V1.3.25 以降、この GUC パラメーターのデフォルト値は
onです。hg_experimental_enable_fixed_dispatcher_for_update
UPDATE 操作の Fixed Plan をサポートします。クライアント側でセッションレベルでこのパラメーターを有効にすることを推奨します。
off
Hologres V1.3.25 以降、
hg_experimental_enable_fixed_dispatcher_for_updateパラメーターは非推奨になりました。条件を満たす UPDATE ステートメントは、デフォルトで Fixed Plan を使用します。複数行を更新するには、set hg_experimental_enable_fixed_dispatcher_for_multi_values =onを設定する必要があります。hg_experimental_enable_fixed_dispatcher_for_delete
DELETE 操作の Fixed Plan をサポートします。クライアント側でセッションレベルでこのパラメーターを有効にすることを推奨します。
off
Hologres V1.3.25 以降、
hg_experimental_enable_fixed_dispatcher_for_deleteパラメーターは非推奨になりました。条件を満たす DELETE ステートメントは、デフォルトで Fixed Plan を使用します。複数行を削除するには、set hg_experimental_enable_fixed_dispatcher_for_multi_values =onを設定する必要があります。hg_experimental_enable_fixed_dispatcher_for_scan
PrefixScan クエリの Fixed Plan をサポートします。
説明PrefixScan クエリは、複数列のプライマリキーの最初の数カラムのみをフィルター条件として使用します。列指向テーブルでの PrefixScan に対する Fixed Plan クエリはサポートされていません。
off
バージョン 1.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 モードでは、各接続が独自の Writer と Reader を持ちます。このモードは単一接続のスループットが高いですが、起動が遅くなります。各テーブルでの最初の読み取りまたは書き込み操作には起動時間が必要です。
cached on fe モードでは、フロントエンド (FE) ノード上のすべての接続が Writer と Reader を共有します。接続が閉じられても Writer と Reader はシャットダウンしません。これにより、起動時間が不要になります。
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 以降、この GUC パラメーターは
ON CONFLICT(<column>)のフィールドが非プライマリキーフィールドであることができるかどうかを制御します。
GUC の使用
GUC が有効かどうかの確認
`SHOW` コマンドを実行して、GUC が有効かどうかを確認できます。
SHOW <GUC_name>;以下にコマンドの使用例を示します。
-- インスタンスレベルで Fixed Plan が有効になっているか確認します。 SHOW hg_experimental_enable_fixed_dispatcher;GUC の有効化
セッションレベルで Grand Unified Configuration (GUC) パラメーターを有効にする
setコマンドを使用して、セッションレベルで GUC パラメーターを設定できます。セッションレベルのパラメーターは現在のセッションでのみ有効です。セッションが閉じられると設定は無効になります。SQL ステートメントの前にコマンドを追加し、一緒に実行することを推奨します。構文は以下の通りです。SET <GUC_name> = <values>;GUC_name は GUC パラメーターの名前を指定し、values は GUC パラメーターの値を指定します。
以下に例を示します。
-- 複数行の insert on conflict レコードに対して Fixed Plan の書き込みを許可します。 SET hg_experimental_enable_fixed_dispatcher_for_multi_values = on;データベースレベルで GUC パラメーターを有効にする
alter database xx set xxxコマンドを使用して、データベースレベルで GUC パラメーターを設定できます。この設定は、コマンド実行後にデータベース全体に適用されます。設定を有効にするには、データベースに再接続する必要があります。この設定は新しいデータベースには適用されません。新しいデータベースには再度手動でパラメーターを設定する必要があります。構文は以下の通りです。ALTER DATABASE <db_name> SET <GUC_name> = <values>;db_name はデータベース名を指定し、GUC_name は GUC パラメーターの名前を指定し、values は GUC パラメーターの値を指定します。
以下に例を示します。
--DB レベルで Fixed Plan を有効にします。 ALTER DATABASE <db_name> SET hg_experimental_enable_fixed_dispatcher = on;
データ型の要件
テーブル内のどの列も MONEY または MONEY ARRAY 型であってはなりません。
INSERT、UPDATE、DELETE などのデータ操作言語 (DML) 操作を実行する列、および SELECT ステートメントの列では、以下のデータ型がサポートされています。SELECT ステートメントのターゲット列と `where` 句の列は、要件を満たす必要があります。
BOOLEAN (エイリアス:BOOL)
SMALLINT
INTEGER (エイリアス:INT または INT4)
BIGINT (エイリアス:INT8)
FLOAT (エイリアス:FLOAT4)
DOUBLE PRECISION (エイリアス:FLOAT8)
CHAR(n)
VARCHAR(n)
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[]
INSERT シナリオ
Hologres V3.2 以降、プライマリキーを持つテーブルで `INSERT` ステートメントを実行する際に、Fixed Plan を使用して `RETURNING` 句がサポートされます。
INSERT ステートメント
Fixed Plan は以下の INSERT 句をサポートします。
-- 単一行を書き込みます。 INSERT INTO TABLE(col1,col2,col3..) VALUES(?,?,?..) ON conflict xxx; -- 複数行を書き込みます。 INSERT INTO TABLE(col1,col2,col3..) VALUES(?,?,?..),(?,?,?..) ON conflict xxx;説明INSERT コマンドは内部テーブルにデータを書き込みますが、外部テーブルには書き込みません。
Hologres は INSERT コマンドを使用したパーティションテーブルへの書き込みをサポートしています。Hologres V1.3 以降では、親パーティションテーブルにも書き込むことができます。
Fixed Plan は INSERT ステートメントの
RETURNINGキーワードをサポートしていません。
単一行の INSERT ON CONFLICT
以下のシナリオがサポートされています。
ON CONFLICTのない句がサポートされています。ON CONFLICT DO NOTHINGのある句がサポートされています。ON CONFLICT DO UPDATEのある句がサポートされています。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 列を更新します。Fixed Plan を使用できます。 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 列を含む) を更新します。Fixed Plan を使用できます。 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; --挿入するすべての非 PK 列を更新する必要があります。この例には col2 は含まれていません。Fixed Plan は Hologres V1.3 以降でのみサポートされます。 INSERT INTO test_insert_oneline VALUES (1, 2, 3, 4) ON CONFLICT (pk1, pk2) DO UPDATE SET col1 = excluded.col1; --更新は `set col = excluded.col` 形式である必要があります。そのため、Fixed Plan は使用できません。 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 1.3.35 以降ではデフォルトでonです。原子性は保証されません。一度に複数の行を書き込む際にエラーが報告されなければ、すべての行が正常に書き込まれます。エラーが報告された場合、すべての行の書き込みが失敗したか、一部が書き込まれて一部が書き込まれなかった可能性があります。
複数行を書き込む別の方法は以下の通りです。
SET hg_experimental_enable_fixed_dispatcher_for_multi_values = ON; INSERT INTO TABLE selectunnest (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` の ARRAY は、対応する列の配列型に明示的にキャストする必要があります。
以下に例を示します。
BEGIN; CREATE TABLE test_insert_multiline ( pk1 int8, col1 float4, PRIMARY KEY (pk1) ); COMMIT; --Fixed Plan がサポートされています。 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 が明示的にキャストされていません。Fixed Plan はサポートされていません。 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[] を使用しています。そのため、Fixed Plan はサポートされていません。 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 では、プライマリキーに基づいてテーブルの一部の列を更新できます。以下の条件が満たされれば、Fixed Plan も部分更新をサポートします。
INSERT ステートメントの列は、数と順序において UPDATE ステートメントの列と一致する必要があります。
更新は
col = excluded.col形式を使用する必要があります。
条件付きチェックを伴う Upsert
同じ PK を持つ行の順不同の入力データを処理し、HBase の CheckAndPut に似たインターフェイスをサポートするために、Hologres は以下の条件が満たされた場合に、条件付きチェックを伴う
INSERTまたはUPDATEステートメントで Fixed Plan を使用できます。これは単一行のデータを挿入する場合にサポートされます。複数行のデータを挿入するには、GUC パラメーターを設定する必要があります:
set hg_experimental_enable_fixed_dispatcher_for_multi_values=on;。WHERE句には単一の非 PK フィールドのみを含めることができます。比較演算子は=, <>, >, >=, <, <=, IS NULL, IS NOT NULLのいずれかでなければなりません。この非 PK フィールドでcoalesce関数を使用できます。
以下にステートメントの使用例を示します。
BEGIN; CREATE TABLE test_check_and_insert ( pk INT, col INT, scn INT, PRIMARY KEY (pk) ); COMMIT; --Fixed Plan がサポートされています。 --列の既存の値を定数と比較します。 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; --Fixed Plan がサポートされています。 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;デフォルト列
デフォルト値を持つ列を含むテーブルで Fixed Plan を使用するには、以下の条件を満たす必要があります。
これは単一行のデータを挿入する場合にサポートされます。複数行のデータを挿入するには、Hologres インスタンスが V1.1.36 以降である必要があります。インスタンスがそれ以前のバージョンの場合は、アップグレードする必要があります。また、GUC パラメーターを設定する必要があります:
set hg_experimental_enable_fixed_dispatcher_for_multi_values=on;。Hologres V1.3 以降のバージョンは、DEFAULT 列を持つテーブルでの
Insert on conflict句の Fixed Plan をサポートします。以前のバージョンでは、DEFAULT 列を持つテーブルでのInsert on conflict句の Fixed Plan はサポートされていません。
以下に例を示します。
BEGIN; CREATE TABLE test_insert_default ( pk1 INT, col1 INT DEFAULT 99, PRIMARY KEY (pk1) ); COMMIT; --Fixed Plan がサポートされています。 INSERT INTO test_insert_default (pk1) VALUES (1); --V1.1.36 以降でサポートされています。 SET hg_experimental_enable_fixed_dispatcher_for_multi_values = ON; INSERT INTO test_insert_default (pk1) VALUES (1), (2), (3);SERIAL 列を持つテーブル
自動インクリメントの SERIAL 列を持つテーブルへの単一行または複数行の書き込みに Fixed Plan を使用するには、以下の条件を満たす必要があります。
GUC パラメーターを設定する必要があります:
set hg_experimental_enable_fixed_dispatcher_autofill_series=on;。Hologres V1.3.25 以降、この GUC パラメーターはデフォルトで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; --Fixed Plan がサポートされています。 SET hg_experimental_enable_fixed_dispatcher_autofill_series = ON; INSERT INTO test_insert_serial (pk1) VALUES (1); --Fixed Plan がサポートされています。 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 ステートメント
以下の UPDATE 句は Fixed Plan を使用できます。
SET hg_experimental_enable_fixed_dispatcher_for_update = ON; UPDATE TABLE SET col1 = ?,col2 = ? WHERE pk1 = ? AND pk2 = ?;UPDATE シナリオ
UPDATE シナリオで Fixed Plan を使用するには、以下の条件を満たす必要があります。
内部テーブルは更新できますが、外部テーブルは更新できません。子パーティションテーブルは更新できますが、親パーティションテーブルは更新できません。テーブルにはプライマリキー (PK) が必要です。
GUC パラメーターを設定する必要があります:
hg_experimental_enable_fixed_dispatcher_for_update=on;。Hologres V1.3.25 以降、このパラメーターは非推奨です。条件を満たすUPDATEステートメントは、デフォルトで Fixed Plan を使用します。複数行を更新するには、GUC パラメーターを設定する必要があります:set hg_experimental_enable_fixed_dispatcher_for_multi_values =on。SET句の列はプライマリキー (PK) であってはなりません。`WHERE` 句には、すべての PK のみを含める必要があります。
pk IN (?,?,?) または pk = ANY()を使用して、一度に複数の行を変更できます。たとえば、pk1 IN (1,2) and pk2 = ANY('{3,4}') and pk3 = 5は 4 つの行(1,3,5), (1,4,5), (2,3,5), and (2,4,5)を変更します。`WHERE` 句の各列には 1 つの条件しか持てません。同一の条件は 1 つとして扱われます。
以下に例を示します。
BEGIN; CREATE TABLE test_update ( pk1 INT, pk2 INT, col1 INT, col2 INT, PRIMARY KEY (pk1, pk2) ); COMMIT; --Fixed Plan がサポートされています。 SET hg_experimental_enable_fixed_dispatcher_for_update = ON; UPDATE test_update SET col1 = 1, col2 = 2 WHERE pk1 = 3 AND pk2 = 4; --Fixed Plan がサポートされています。 SET hg_experimental_enable_fixed_dispatcher_for_update = ON; UPDATE test_update SET col1 = 1 WHERE pk1 = 3 AND pk2 = 4; --Fixed Plan がサポートされています。 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}'); --pk1 には複数のフィルター条件があります。Fixed Plan はサポートされていません。 UPDATE test_update SET col1 = 1, col2 = 2 WHERE pk1 = 3 AND pk1 = 4; --pk1 には複数のフィルター条件があります。Fixed Plan はサポートされていません。 UPDATE test_update SET col1 = 1, col2 = 2 WHERE pk1 IN (1, 2) AND pk1 = 1; --pk1 には複数のフィルター条件がありますが、条件は同一です。Fixed Plan はサポートされています。 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 ステートメント
以下の DELETE 句は Fixed Plan を使用できます。
SET hg_experimental_enable_fixed_dispatcher_for_delete = ON; DELETE FROM TABLE WHERE pk1 = ? AND pk2 = ? AND pk3 = ?;DELETE シナリオ
DELETE シナリオで Fixed Plan を使用するには、以下の条件を満たす必要があります。
内部テーブルからは削除できますが、外部テーブルからは削除できません。子パーティションテーブルからは削除できますが、親パーティションテーブルからは削除できません。テーブルにはプライマリキー (PK) が必要です。
GUC パラメーターを設定する必要があります:
hg_experimental_enable_fixed_dispatcher_for_delete=on;。Hologres V1.3.25 以降、このパラメーターは非推奨です。DELETEステートメントが条件を満たす場合、デフォルトで Fixed Plan を使用します。複数行を削除するには、GUC パラメーターを設定する必要があります:set hg_experimental_enable_fixed_dispatcher_for_multi_values =on。WHERE句には、すべての PK のみを含める必要があります。Hologres V1.3 以降、WHEREフィルター条件の最後のフィールドは非 PK フィールドにすることができます。この非 PK フィールドは、=, <>, >, >=, <, <=, IS NULL, and IS NOT NULL比較演算子とcoalesce関数をサポートします。pk IN (?,?,?) または pk = ANY()を使用して、一度に複数の行を削除できます。たとえば、pk1 IN (1,2) and pk2 = ANY('{3,4}') and pk3 = 5は 4 つの行(1,3,5), (1,4,5), (2,3,5), and (2,4,5)を削除します。各列には 1 つの条件しか持てません。同一の条件は 1 つとして扱われます。
以下に例を示します。
BEGIN; CREATE TABLE test_delete ( pk1 INT, pk2 INT, col1 INT, col2 INT, PRIMARY KEY (pk1, pk2) ); COMMIT; --Fixed Plan がサポートされています。その他のシナリオは UPDATE の例と一致します。 SET hg_experimental_enable_fixed_dispatcher_for_delete = ON; DELETE FROM test_delete WHERE pk1 = 1 AND pk2 = 2;
SELECT シナリオ
SELECT ステートメント
以下の SELECT 句は Fixed Plan を使用できます。
SELECT col1, col2, col3, ... FROM TABLE WHERE pk1 = ? AND pk2 = ? AND pk3 = ?;内部テーブルからは選択できますが、外部テーブルからは選択できません。
子パーティションテーブルからは選択できますが、親パーティションテーブルからは選択できません。
テーブルにはプライマリキー (PK) が必要です。
ポイントクエリ (キー・バリュー) シナリオ
ポイントクエリシナリオには以下の条件が適用されます。
`WHERE` 句には、すべての PK のみを含める必要があります。
pk IN (?,?,?) または pk = ANY()を使用して、一度に複数の行をクエリできます。たとえば、pk1 IN (1,2) and pk2 = ANY('{3,4}') and pk3 = 5は 4 つの行(1,3,5), (1,4,5), (2,3,5), and (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; --Fixed Plan がサポートされています。 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 < ?;--V1.1.48 以降、最後の PK 列は範囲条件を持つことができます。 SELECT col1,col2,col3,... FROM TABLE WHERE pk1 = ? AND pk2 BETWEEN ? AND ?;--V1.1.48 以降、最後の PK 列は範囲条件を持つことができます。PrefixScan の使用
PrefixScan を使用するには、以下の条件を満たす必要があります。
GUC パラメーターを設定する必要があります:
hg_experimental_enable_fixed_dispatcher_for_scan=on;。Hologres インスタンスは V1.3.35 以降である必要があります。テーブルには Distribution Key が必要で、
WHERE句にはすべての Distribution Key を含める必要があります。WHERE句には PK のプレフィックスのみを含める必要があります。V1.1.48 以降、PrefixScan は最後のプライマリキー列に上限と下限を含む範囲を設定することをサポートします。説明プレフィックスの定義: PK が
(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) です。たとえば、テーブルの PK が
(pk1,pk2,pk3,pk4)で、Distribution Key が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; --すべての distribution key が含まれていません。Fixed Plan は使用できません。 SELECT * FROM test_select_prefix WHERE pk1 = ? AND pk2 = ?; --これは PK のプレフィックスではありません。Fixed Plan は使用できません。 SELECT * FROM test_select_prefix WHERE pk1 = ? AND pk3 = ?; --Fixed Plan を使用できます。 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); --Fixed Plan がサポートされています。 SET hg_experimental_enable_fixed_dispatcher_for_scan = ON; SELECT * FROM test_scan WHERE pk1 = 1 AND pk2 = 2; --Fixed Plan がサポートされています。 SET hg_experimental_enable_fixed_dispatcher_for_scan = ON; SELECT * FROM test_scan WHERE pk1 = 1 AND pk2 IN (2, 3); --Fixed Plan がサポートされています。 SET hg_experimental_enable_fixed_dispatcher_for_scan = ON; SELECT * FROM test_scan WHERE pk1 = ANY ('{3,4}') AND pk2 IN (2, 3); --Fixed Plan がサポートされています。最後の PK 列には範囲条件があります。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; --Fixed Plan がサポートされています。最後の PK 列には範囲条件があります。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; --すべての distribution key が含まれていません。Fixed Plan はサポートされていません。 SELECT * FROM test_scan WHERE pk1 = 1; --プライマリキーのプレフィックスと一致しません。Fixed Plan はサポートされていません。 SELECT * FROM test_scan WHERE pk2 = 2;
ページクエリシナリオ
Hologres V3.2 以降、Fixed Plan は部分的なプライマリキーに基づく PrefixScan シナリオでのページクエリをサポートします。以下の例でその仕組みを示します:
説明デフォルトでは、PrefixScan の結果はプライマリキーの昇順で返されます。たとえば、以下の SQL ステートメントでは、`pk1` と `pk2` に基づく PrefixScan は `pk3` の昇順でソートされた結果を返します。
カスタムのソート順を指定するには、Clustering Key で対応する列の順序を設定し、クエリ実行時に関連する GUC を指定します。結果は Clustering Key によってソートされます。Clustering Key のフィールドはプライマリキーと同一でなければなりません。たとえば、結果を降順で返すには、Clustering Key の最後の項目を手動で
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); -- 以下の 2 つの GUC を有効にします。結果は pk3 の降順でソートされます。 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 Plan をサポートします。この機能は 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` コマンドが列のサブセットに書き込む場合、以下のように部分更新を実行します:
CREATE TABLE t0 ( id INT NOT NULL, name TEXT, age INT, PRIMARY KEY (id) ); COPY t0 (id, name) FROM STDINWITH (stream_mode TRUE, on_conflict UPDATE); -- 上記の COPY ステートメントは、以下のステートメントと同等です 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 STDINWITH (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;
式に対する Fixed Plan のサポート
Hologres V3.2 以降、Fixed Plan は式を含む SQL ステートメントをサポートします。PostgreSQL の式の詳細については、「PostgreSQL Expressions」をご参照ください。式は以下のシナリオでサポートされます:
INSERT ステートメント:
VALUES 句。
INSERT ON CONFLICT DO UPDATE 句。
INSERT ON CONFLICT WHERE 句のフィルター条件。
RETURNING 句。
SELECT ステートメント
SELECT リストのフィールド。
制限事項
スカラー式とスカラー関数のみがサポートされます。集計関数、ウィンドウ関数、またはサブクエリはサポートされていません。
INSERT ステートメントの場合、VALUES 句以外の句の式または関数は、Hologres クエリエジンで実行可能でなければなりません。
SELECT ステートメントの場合、IMMUTABLE な式と関数のみがサポートされます。関数は定数入力パラメーターもサポートする必要があります。
この機能を使用するには、以下のパラメーターを有効にする必要があります:
-- セッションレベルで有効にします。 SET hg_experimental_enable_fixed_plan_expression = on; -- DB レベルで有効にします。 ALTER DATABASE <db_name> SET hg_experimental_enable_fixed_plan_expression = on;
使用例
4 種類の INSERT 句における式
-- テーブルを作成します。 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;
SELECT ステートメントの場合、非 IMMUTABLE 関数や定数入力パラメーターをサポートしない関数が関与するシナリオでは、Fixed Plan の最適化は使用できません。
-- テーブルを作成します。 CREATE TABLE test_t ( id INT PRIMARY KEY, ts TIMESTAMP NOT NULL, col JSONB ) WITH ( orientation = 'row', distribution_key = 'id' ); -- random() 関数は不変ではなく、Fixed Plan ではサポートされていません。 SELECT id + random() FROM test_t WHERE id = 1; -- toString 関数は定数入力パラメーターをサポートしておらず、Fixed Plan ではサポートされていません。 SELECT toString (id) FROM test_t WHERE id = 1;
Fixed Plan の検証
INSERT、UPDATE、DELETE 操作を含む、Fixed Plan を使用して実行されるデータを変更する SQL ステートメントは、コンソールのリアルタイムインポート RPS パネルに SDK タイプとして表示されます。データ更新効率を向上させるために、INSERT、UPDATE、DELETE などのリアルタイム書き込み操作を Fixed Plan を使用するように最適化することを推奨します。以下の図は、モニタリングメトリックの例を示しています。

`EXPLAIN` を使用して SQL 実行計画を表示できます。返された実行計画に
FixedXXXNodeが含まれている場合、Fixed Plan がトリガーされたことを示します (以下の図を参照)。生成された実行計画にFixedXXXNodeが含まれていない場合は、前のセクションで説明した条件が満たされているか確認してください。
パフォーマンスチューニング
Fixed Plan を有効にしてもパフォーマンスチューニングが必要な場合は、以下の方法を使用できます。
Hologres V1.1.49 以降では、Fixed Plan のポイントクエリシナリオのパフォーマンスが最適化されています。大規模なポイントクエリのスループットが 30% 以上向上します。必要に応じて、インスタンスを V1.1.49 以降にアップグレードできます。
クライアントで適切なバッチサイズを使用します。Holo Client はリクエストを自動的にバッチ処理します。512 または 512 の倍数のバッチサイズを使用すると、パフォーマンスが向上します。
FAQ
質問 1:接続に失敗し、
role/database does not exist.というエラーが表示されます。原因:ユーザーまたはデータベースが存在しません。
解決策:接続情報を確認し、正しいユーザー名またはデータベース名を入力してください。
Hologres 管理コンソールにログインし、対象のインスタンスを見つけ、Actions 列の Manage をクリックし、次に Database Management をクリックします。Users および Database Authorization ページでユーザー名またはデータベース名を確認できます。
質問 2:データ書き込み中に
the requested table name: xxx (id: xx, version: xx) mismatches the version of the table (id: xx, version: xx) from server.というエラーが発生します。原因:データ書き込みプロセス中にテーブルのメタデータが変更されました。たとえば、列が追加されたなどです。これにより、テーブルのバージョンが変更されました。
解決策:接続を再確立してください。Fixed Plan は新しいテーブルメタデータを取得し、書き込み操作を実行します。