すべてのプロダクト
Search
ドキュメントセンター

Hologres:Fixed Plan を活用した SQL 実行の高速化

最終更新日:Feb 14, 2026

Fixed Plan は、Hologres 実行エンジンに特化した最適化機能です。本トピックでは、SQL 文が Fixed Plan を利用するための条件およびパラメーター設定について説明します。

背景情報

Fixed Plan は、Hologres 実行エンジンに特化した最適化機能です。従来の SQL 実行には、オプティマイザー、コーディネーター、クエリーエンジン、ストレージエンジンなど、複数のコンポーネントが関与します。Fixed Plan では、オプティマイザー、コーディネーター、およびクエリーエンジンの一部のオーバーヘッドをバイパスするショートカット経路を採用し、Fixed FrontEnd を Fixed Query Engine に直接接続することで、SQL 実行効率を大幅に向上させます。これは、高スループットのリアルタイム書き込みおよび高並列性のクエリーを実現するためのキーメソッドです。Fixed Plan の詳細については、「サービスアーキテクチャ」をご参照ください。

Hologres では、以下のシナリオで Fixed Plan がデフォルトで使用されます。

  • Flink から Hologres へのリアルタイムデータ書き込み。

  • Data Integration から Hologres へのリアルタイムデータ書き込み。

  • Holo Client から Hologres へのデータ書き込み。

その他の書き込みシナリオでは、SQL 文を Fixed Plan で実行するよう明示的に設定できます。詳細については、以降のセクションをご参照ください。

説明

上記のシナリオでは、条件を満たす SQL 文に対して Fixed Plan がデフォルトで適用されますが、これらのシナリオにおけるすべての SQL 文が必ずしも Fixed Plan の条件を満たすとは限りません。

関連する GUC パラメーター

  • 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件のエラーのみが報告されます。これは、レコードが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

    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:各接続ごとに独自の 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 に設定すると、ON CONFLICT 句の列としてプライマリキー以外のフィールドを指定できます。ただし、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 パラメーターの有効化

      • セッションレベルで GUC パラメーターを有効化する

        set コマンドを実行して、GUC パラメーターをセッションレベルで設定します。セッションレベルのパラメーターは、現在のセッションでのみ有効であり、接続が終了すると無効になります。SQL 文の前にコマンドを追加し、両方をまとめて実行します。構文は以下のとおりです。

        SET <GUC_name> = <values>;

        GUC_name は GUC パラメーターの名前、values はその値です。

        以下の例は、コマンドの使用方法を示しています。

        -- 複数レコードの 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 はその値です。

        以下の例は、コマンドの使用方法を示しています。

        -- DB レベルで Fixed Plan を有効化します。
        ALTER DATABASE <db_name> SET hg_experimental_enable_fixed_dispatcher = on;

データ型の要件

  • テーブル内のどの列も MONEY 型または MONEY ARRAY 型であってはなりません。

  • データ操作言語(DML)操作(INSERT、UPDATE、DELETE、SELECT)および 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 型が Fixed Plan をサポート)

    • 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 以降では、プライマリキーを持つテーブルに対する Fixed Plan INSERT 操作で 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 コマンドは内部テーブルへのデータ書き込みに使用できますが、外部テーブルには使用できません。

    • INSERT コマンドはパーティションテーブルへのデータ書き込みに使用できます。Hologres V1.3 以降では、パーティションテーブルの親テーブルへの書き込みも可能です。

    • Hologres V3.2 より前のバージョンでは、INSERT 文は RETURNING キーワードをサポートしていません。このキーワードは Hologres V3.2 以降でサポートされます。

  • 単一レコードの 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 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 関数内の 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 句の列と 1 対 1 に対応している必要があります。

    • 更新は col = excluded.col 形式で記述する必要があります。

  • 条件付き Upsert

    同一 PK の行に対する順不同の入力データを処理するために、Hologres は HBase の CheckAndPut インターフェイスと同様の、Fixed Plan を使用した条件付き INSERT または UPDATE 文をサポートします。以下の条件を満たす必要があります。

    • 単一レコードの挿入時にサポートされます。複数レコードの挿入時には、GUC パラメーターを設定する必要があります:set hg_experimental_enable_fixed_dispatcher_for_multi_values=on;

    • where 句では、単一の非 PK フィールドのみがサポートされます。比較演算子は =, <>, >, >=, <, <=, IS NULL, または IS NOT NULL のいずれかである必要があります。coalesce 関数をこの非 PK フィールドに使用できます。

    以下の例は、文の使用方法を示しています。

    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 以降では、デフォルト列を持つテーブルに対する Insert on conflict 句で Fixed Plan がサポートされます。それより前のバージョンでは、デフォルト列を持つテーブルに対する 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);
  • シリアル列

    テーブルに自動インクリメントのシリアル列がある場合、単一または複数レコードの書き込みに対して 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 以外の列は含まれてはなりません。Hologres V1.3 以降では、WHERE 句の最後のフィールドとして非 PK フィールドを指定できます。この非 PK フィールドに対しては、比較演算子 =, <>, >, >=, <, <=, IS NULL, および IS NOT NULL および coalesce 関数がサポートされます。

    • pk in (?,?,?) or pk = ANY() を使用して、複数のレコードを一度に更新できます。例:pk1 in (1,2) and pk2 = any('{3,4}') and pk3 = 5 では、(1,3,5), (1,4,5), (2,3,5), および (2,4,5) の 4 つのレコードが更新されます。

    • 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 がサポートされます(Hologres V1.3+、WHERE 句に非 PK フィールドを含む)。
    SET hg_experimental_enable_fixed_dispatcher_for_update = ON;
    UPDATE test_update SET col1 = 1 WHERE pk1 = 3 AND pk2 = 4 AND col1 > 3;
    
    -- Fixed Plan がサポートされます(Hologres V1.3+、WHERE 句に非 PK フィールドと coalesce を含む)。
    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;
    
    -- 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}');
    
    -- Fixed Plan がサポートされます(Hologres V1.3+、WHERE 句に非 PK フィールドを含む)。
    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 に複数のフィルター条件があります。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 が含まれ、かつ PK 以外の列は含まれてはなりません。Hologres V1.3 以降では、where 句の最後のフィールドとして非 PK フィールドを指定できます。この非 PK フィールドに対しては、比較演算子 =, <>, >, >=, <, <=, IS NULL, および IS NOT NULL および coalesce 関数がサポートされます。

    • pk in (?,?,?) or pk = ANY() を使用して、複数のレコードを一度に削除できます。例:pk1 in (1,2) and pk2 = any('{3,4}') and pk3 = 5 では、(1,3,5), (1,4,5), (2,3,5), および (2,4,5) の 4 つのレコードが削除されます。

    • 各列には、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 以外の列は含まれてはなりません。

    • pk in (?,?,?) or pk = ANY() を使用して、複数のレコードを一度にクエリーできます。例: pk1 in (1,2) and pk2 = any('{3,4}') and pk3 = 5 では、(1,3,5), (1,4,5), (2,3,5), および (2,4,5) の 4 つのレコードがクエリーされます。

    • 各列には、1 つの条件のみを指定できます。同一の条件は、1 つの条件として扱われます。

    • LIMIT 句が存在する場合、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 以降である必要があります。

      • テーブルには分散キーが必要であり、where 句には、すべての分散キー列が含まれている必要があります。

      • where 句には、PK のプレフィックスのみが含まれている必要があります。Hologres V1.1.48 以降では、PK の最後の列に対して範囲条件(上限および下限の両方)を設定できます。

        説明

        プレフィックスの定義:PK が (pk1,pk2,pk3) の場合、(pk1),(pk1,pk2) がプレフィックスです。

      • PrefixScan は、行指向テーブル(行・列ハイブリッドテーブルを含む)のみがサポートされます。

      • 各列には、1 つの条件のみを指定できます。同一の条件は、1 つの条件として扱われます。

      • LIMIT 条件が存在する場合、LIMIT 値は 0 より大きい必要があります。

      説明

      PrefixScan は、すべての結果行を一度に返します。結果のサイズ(バイト単位)が hg_experimental_fixed_scan_bytesize_limit を超えると、エラー「scan result size larger than fixed scan size limit」が報告されます。この hg_experimental_fixed_scan_bytesize_limit パラメーターを、ご利用のシナリオに適した値に設定できます。デフォルト値は 1048576(1 MB)です。

      たとえば、テーブルの PK が (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;
      
      -- すべての分散キーが含まれていません。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 <=> scan(1,3),(2,3) two groups
      pk2 =any('{3,4}') AND pk1 IN (1,2) <=> scan(1,3),(1,4),(2,3),(2,4) four groups
    • 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;
      
      -- すべての分散キーが含まれていません。Fixed Plan はサポートされません。
      SELECT * FROM test_scan WHERE pk1 = 1;
      
      -- PK のプレフィックスに一致していません。Fixed Plan はサポートされません。
      SELECT * FROM test_scan WHERE pk2 = 2;
  • ページングシナリオ

    Hologres V3.2 以降では、Fixed Plan は、部分的なプライマリキーに基づく PrefixScan シナリオにおけるページングクエリーをサポートします。以下の例は、この機能の使用方法を示しています。

    説明
    • デフォルトでは、Prefix Scan の結果はプライマリキーの昇順で返されます。以下の 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 がサポートされます。Prefix Scan を基に、指定された行から指定された行数を返します。
      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 1.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
        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;
    

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 句以外の句における式または関数は、HQE で実行可能である必要があります。

  • SELECT 文では、IMMUTABLE 式または関数のみがサポートされ、関数は定数入力パラメーターをサポートする必要があります。

  • この機能を使用するには、以下のパラメーターを有効化する必要があります。

    -- セッションレベルで有効化します。
    SET hg_experimental_enable_fixed_plan_expression = on;
    
    -- DB レベルで有効化します。
    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 シナリオ(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() 関数は IMMUTABLE 関数式ではありません。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 の検証

  • Fixed Plan を使用して実行された INSERT、UPDATE、DELETE などの更新系 SQL 文は、コンソールの「リアルタイムインポート RPS」パネルで SDK タイプとして表示されます。INSERT、UPDATE、DELETE などのリアルタイム書き込み操作を Fixed Plan を使用するように最適化することで、データ更新効率を向上させることができます。以下の図は、モニタリングメトリックの例です:RPS

  • EXPLAIN コマンドを実行して、SQL 実行計画を表示します。返された実行計画に FixedXXXNode が含まれている場合、Fixed Plan がトリガーされます(以下の図を参照)。FixedXXXNode を含む実行計画が生成されない場合は、前述のセクションで説明した条件を満たしているかどうかを確認してください。验证fixedplan

パフォーマンスチューニング

Fixed Plan を有効化しましたが、それでもパフォーマンスをチューニングする必要がある場合は、以下の方法をご利用ください。

  • 実行計画を表示して、Fixed Plan のパフォーマンスボトルネックを特定します:SQL 実行計画(EXPLAIN)を表示して、Fixed Plan の各フェーズで消費される時間を分析し、パフォーマンスボトルネックを特定できます。

  • Hologres V1.1.49 以降では、Fixed Plan のポイントクエリーシナリオが最適化されており、大規模なポイントクエリーにおいてスループットを 30% 以上向上させることができます。必要に応じて、インスタンスを V1.1.49 以降にアップグレードしてください。

  • クライアント側で適切なバッチサイズを使用します。Holo Client はデータを自動的にバッチ処理します。バッチサイズとは、一度に実行される SQL コマンドの数です。実際には、バッチサイズが 512 または 512 の倍数の場合にパフォーマンスが向上します。

よくある質問

  • 問題 1:接続エラー:「role/database does not exist.

    • 原因:ユーザーまたは DB が存在しません。

    • 解決策:接続情報を確認し、正しいユーザー名または DB 名を入力してください。

      Hologres 管理コンソール にログインし、対象インスタンスの「Actions」をクリックし、「Manage」列から「Database Management」をクリックします。「Users」および「Database Authorization」ページで、ユーザー名または DB 名を確認してください。

  • 問題 2:データ書き込み中にエラーが発生:「the requested table name: xxx (id: xx, version: xx) mismatches the version of the table (id: xx, version: xx) from server.

    • 原因:データ書き込みプロセス中に、列の追加などのテーブルメタデータが変更され、テーブルのバージョンが変更されました。

    • 解決策:接続を再確立してください。Fixed Plan は新しいテーブルメタデータを取得し、書き込み操作を実行します。