Tous les produits
Search
Centre de documentation

Hologres:Accelerate SQL execution with fixed plans

Dernière mise à jour :Aug 11, 2026

Un plan fixe est une fonctionnalité d'optimisation du moteur d'exécution propre à Hologres. Cette rubrique décrit les prérequis et la configuration des paramètres nécessaires pour qu'une instruction SQL puisse bénéficier d'un plan fixe.

Contexte

Le plan fixe constitue une méthode d'optimisation du moteur d'exécution exclusive à Hologres. L'exécution traditionnelle d'une requête SQL fait intervenir plusieurs composants, tels que l'optimiseur, le coordinateur, le moteur de requête et le moteur de stockage. À l'inverse, un plan fixe emprunte un chemin direct qui contourne l'optimiseur, le coordinateur et certaines parties du moteur de requête, réduisant ainsi la surcharge de traitement. Le frontal fixe se connecte directement au moteur de requête fixe, ce qui améliore considérablement l'efficacité de l'exécution SQL. Cette optimisation clé permet d'assurer des écritures en temps réel à haut débit et des requêtes à forte concurrence. Pour plus d'informations sur les plans fixes, consultez architecture du produit.

Dans Hologres, les plans fixes sont utilisés par défaut dans les scénarios suivants :

  • Écritures en temps réel vers Hologres via Flink.

  • Écritures en temps réel vers Hologres via Data Integration de DataWorks.

  • Écritures vers Hologres via Holo Client.

Pour les autres scénarios d'écriture, vous pouvez configurer vos instructions SQL afin qu'elles utilisent un plan fixe. Consultez les sections suivantes pour plus de détails.

Remarque

Dans ces scénarios, Hologres utilise par défaut des plans fixes pour les instructions SQL éligibles. Toutefois, toutes les instructions SQL de ces scénarios ne sont pas nécessairement éligibles.

Paramètres GUC associés

  • Liste des paramètres GUC

    Les paramètres suivants servent à configurer Fixed Plan. La valeur de chaque paramètre peut être on ou off. Tous les paramètres sont activés par défaut dans Holo Client et s'appliquent au niveau de la session.

    Paramètre

    Description

    Valeur par défaut

    Historique des modifications

    hg_experimental_enable_fixed_dispatcher

    Contrôle l'activation de la fonctionnalité de plan fixe pour l'instance.

    Prend en charge les plans fixes pour les opérations INSERT, UPDATE, DELETE et PrefixScan portant sur une seule ligne.

    on

    S.O.

    hg_experimental_enable_fixed_dispatcher_for_multi_values

    Détermine si un plan fixe doit être utilisé pour les opérations INSERT multi-lignes.

    Remarque

    L'atomicité n'est pas garantie. Pour les insertions multi-lignes, une opération réussie signifie que toutes les lignes ont été insérées. En cas d'erreur, le système renvoie un seul message pouvant indiquer soit une insertion partielle, soit un échec complet. Il incombe à l'application cliente de retenter l'insertion des lignes ayant échoué.

    on

    À partir de Hologres V1.3.35, ce paramètre GUC permet aux opérations INSERT, UPDATE et DELETE multi-lignes d'utiliser des plans fixes.

    hg_experimental_enable_fixed_dispatcher_autofill_series

    Prend en charge les plans fixes pour les écritures dans les tables contenant des colonnes de type SERIAL. Nous recommandons d'activer ce paramètre au niveau de la session.

    on

    La valeur par défaut est passée à on dans Hologres V1.3.25.

    hg_experimental_enable_fixed_dispatcher_for_update

    Prend en charge les plans fixes pour les opérations UPDATE. Nous recommandons d'activer ce paramètre au niveau de la session.

    off

    À partir de Hologres V1.3.25, le paramètre hg_experimental_enable_fixed_dispatcher_for_update est obsolète. Les instructions UPDATE éligibles utilisent un plan fixe par défaut. Toutefois, pour mettre à jour plusieurs lignes, vous devez configurer set hg_experimental_enable_fixed_dispatcher_for_multi_values = on.

    hg_experimental_enable_fixed_dispatcher_for_delete

    Prend en charge les plans fixes pour les opérations DELETE. Nous recommandons d'activer ce paramètre au niveau de la session.

    off

    À partir de Hologres V1.3.25, le paramètre hg_experimental_enable_fixed_dispatcher_for_delete est obsolète. Les instructions DELETE éligibles utilisent un plan fixe par défaut. Toutefois, pour supprimer plusieurs lignes, vous devez configurer set hg_experimental_enable_fixed_dispatcher_for_multi_values = on.

    hg_experimental_enable_fixed_dispatcher_for_scan

    Prend en charge les plans fixes pour les requêtes PrefixScan.

    Remarque

    Une requête PrefixScan interroge une table dotée d'une clé primaire composite, où les conditions de la requête ne spécifient que les premières colonnes de la clé primaire. Les plans fixes pour les requêtes PrefixScan sur des tables orientées colonne ne sont actuellement pas pris en charge.

    off

    Hologres V1.3.35 ou version ultérieure recommandé.

    hg_experimental_enable_bhclient_cache_on_session

    Contrôle le mode de mise en cache. Deux modes sont disponibles.

    • on : Utilise le mode cached on session.

    • off : Utilise le mode cached on fe.

    Remarque

    La liste suivante compare les modes cached on session et cached on fe.

    • cached on session : Chaque session dispose de son propre writer et reader. Ce mode offre un débit plus élevé par session, mais le démarrage est plus lent, car le writer et le reader nécessitent une initialisation avant la première opération sur chaque table.

    • cached on fe : Toutes les sessions d'un nœud FE partagent les mêmes writers et readers. Les writers et readers ne sont pas fermés à la fin d'une session, ce qui élimine le temps de démarrage.

    off

    S.O.

    hg_experimental_disable_fixed_planner_conflict_pk_check

    Détermine si la colonne spécifiée dans la syntaxe INSERT INTO <table_name> VALUES (...) ON CONFLICT(<column>) peut être une colonne non liée à la clé primaire.

    • false : Non pris en charge.

    • true : Pris en charge.

      Remarque

      Si ce paramètre GUC est défini sur true, vous pouvez spécifier une colonne non liée à la clé primaire. Toutefois, l'instruction INSERT ON CONFLICT continue de traiter les données en fonction de la duplication de la clé primaire, comme si ON CONFLICT(pk) avait été spécifié.

    false

    • Dans les versions de Hologres allant de la V1.3 à la V2.1.28, la colonne spécifiée dans ON CONFLICT(<column>) doit être une colonne de clé primaire.

    • Ce paramètre est disponible uniquement dans Hologres V2.1.29 et les versions ultérieures de la série V2.1.x. Il détermine si la colonne dans ON CONFLICT(<column>) peut être une colonne non liée à la clé primaire. Ce paramètre est supprimé dans la V3.0 et les versions ultérieures ; aucune configuration n'est alors requise.

  • Utilisation des paramètres GUC

    • Vérifier la valeur d'un paramètre GUC

      Utilisez la commande SHOW pour vérifier la valeur d'un paramètre GUC.

      SHOW <GUC_name>;

      Exemple :

      -- Check whether the fixed plan feature is enabled at the instance level.
      SHOW hg_experimental_enable_fixed_dispatcher;
    • Définir un paramètre GUC

      • Définir un paramètre GUC au niveau de la session

        Vous pouvez utiliser la commande SET pour configurer un paramètre GUC au niveau de la session. Le paramétrage s'applique uniquement à la session actuelle et est ignoré lors de sa fermeture. Nous vous recommandons d'inclure cette commande avant votre instruction SQL.

        SET <GUC_name> = <values>;

        GUC_name indique le nom du paramètre GUC, et values indique la valeur du paramètre.

        Exemple :

        -- Enable fixed plan for multi-row INSERT ON CONFLICT statements.
        SET hg_experimental_enable_fixed_dispatcher_for_multi_values = on;
      • Définir un paramètre GUC au niveau de la base de données

        Utilisez la commande ALTER DATABASE ... SET ... pour définir un paramètre GUC au niveau de la base de données. Le paramétrage s'applique à l'ensemble de la base de données. Pour appliquer la modification à la session actuelle, vous devez vous reconnecter. Ce paramétrage ne s'applique pas aux nouvelles bases de données ; vous devez le configurer manuellement pour chacune d'elles.

        ALTER DATABASE <db_name> SET <GUC_name> = <values>;

        db_name indique le nom de la base de données, GUC_name indique le nom du paramètre GUC, et values indique la valeur du paramètre.

        Exemple :

        -- Enable the fixed plan feature at the database level.
        ALTER DATABASE <db_name> SET hg_experimental_enable_fixed_dispatcher = on;

Exigences relatives aux types de données

  • Les colonnes d'une table ne peuvent pas être de type MONEY ni MONEY ARRAY.

  • Les types de données suivants sont pris en charge pour les colonnes utilisées dans les opérations DML (INSERT, UPDATE et DELETE) et SELECT. Pour les instructions SELECT, cette exigence s'applique à la fois aux colonnes cibles et aux colonnes figurant dans la clause WHERE.

    • BOOLEAN (alias : BOOL)

    • SMALLINT

    • INTEGER (alias : INT, INT4)

    • BIGINT (alias : INT8)

    • FLOAT (alias : FLOAT4)

    • DOUBLE PRECISION (alias : FLOAT8)

    • CHAR(n)

    • VARCHAR(n) (Dans Hologres V1.1.79 et versions ultérieures, VARCHAR peut utiliser Fixed Plan.)

    • BYTEA

    • JSON et JSONB

    • TEXT (alias : VARCHAR)

    • TIMESTAMP WITH TIME ZONE (alias : TIMESTAMPTZ)

    • DATE

    • TIMESTAMP

    • DECIMAL (alias : NUMERIC)

    • ROARINGBITMAP

    • TIME (pris en charge dans Hologres V2.2 et versions ultérieures)

    • TIMETZ (pris en charge dans Hologres V2.2 et versions ultérieures)

    • Types tableau

      • boolean[]

      • smallint[]

      • int4[]

      • int8[]

      • float4[]

      • float8[]

      • char(n)[]

      • varchar(n)[]

      • text[]

Scénarios d'insertion

À partir de Hologres V3.2, vous pouvez utiliser la clause RETURNING dans une instruction INSERT qui utilise un plan fixe pour écrire dans une table dotée d'une clé primaire.

  • Instruction INSERT

    Un plan fixe peut être utilisé avec les instructions INSERT suivantes.

    -- Write a single row.
    INSERT INTO TABLE(col1,col2,col3..) VALUES(?,?,?..) ON conflict xxx;
    -- Write multiple rows.
    INSERT INTO TABLE(col1,col2,col3..) VALUES(?,?,?..),(?,?,?..) ON conflict xxx;
    Remarque
    • Vous pouvez utiliser l'instruction INSERT pour écrire des données dans des tables internes, mais pas dans des tables externes.

    • Vous pouvez utiliser l'instruction INSERT pour écrire des données dans une table partitionnée. Hologres V1.3 et versions ultérieures prennent également en charge l'écriture dans une table partitionnée parente.

    • Le mot-clé RETURNING n'est pas pris en charge dans les instructions INSERT des versions de Hologres antérieures à la V3.2. Il est pris en charge à partir de Hologres V3.2.

  • INSERT ON CONFLICT mono-ligne

    • Les scénarios suivants sont pris en charge :

      • Une instruction INSERT sans clause ON CONFLICT.

      • Une instruction INSERT avec une clause ON CONFLICT DO NOTHING.

      • Une instruction INSERT avec une clause ON CONFLICT DO UPDATE. Pour utiliser un plan fixe, vous devez mettre à jour toutes les colonnes non liées à la clé primaire (non-PK) spécifiées dans l'instruction INSERT. Vous pouvez éventuellement mettre à jour les colonnes de clé primaire (PK). La mise à jour doit utiliser le format col = excluded.col. Dans Hologres V1.3 et versions ultérieures, vous pouvez mettre à jour un sous-ensemble de colonnes non-PK, mais le format col = excluded.col reste requis.

    • Exemple :

      BEGIN;
      CREATE TABLE test_insert_oneline (
          pk1 INT,
          pk2 INT,
          col1 INT,
          col2 INT,
          PRIMARY KEY (pk1, pk2)
      );
      COMMIT;
      
      -- Update all non-PK columns. A Fixed Plan can be used.
      INSERT INTO test_insert_oneline
          VALUES (1, 2, 3, 4)
      ON CONFLICT (pk1, pk2)
          DO UPDATE SET
              col1 = excluded.col1, col2 = excluded.col2;
      
      -- Update all columns, including PK and non-PK columns. A Fixed Plan can be used.
      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;
      
      -- A Fixed Plan requires updating all non-PK columns specified in the INSERT statement. Because col2 is omitted, this statement is supported only in Hologres V1.3 and later.
      INSERT INTO test_insert_oneline
          VALUES (1, 2, 3, 4)
      ON CONFLICT (pk1, pk2)
          DO UPDATE SET
              col1 = excluded.col1;
      
      -- A Fixed Plan is not supported because the update uses a literal value instead of the required 'col = excluded.col' format.
      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 multi-lignes

    • Pour les opérations INSERT ON CONFLICT multi-lignes, utilisez la syntaxe suivante :

      SET hg_experimental_enable_fixed_dispatcher_for_multi_values = ON;
      
      INSERT INTO TABLE (col1, col2, col3..)
          VALUES (?, ?, ?..), (?, ?, ?..)
      ON CONFLICT xxx;
      • Vous devez définir le paramètre GUC hg_experimental_enable_fixed_dispatcher_for_multi_values = on;. Dans Hologres V1.3.35 et versions ultérieures, ce paramètre est défini sur on par défaut.

      • Ces opérations ne garantissent pas l'atomicité. Une opération réussie écrit toutes les lignes. En cas d'erreur, certaines lignes ou aucune ligne n'auront peut-être été écrites.

    • Vous pouvez également utiliser la syntaxe suivante pour écrire plusieurs lignes :

      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;
      • Vous devez définir le paramètre GUC hg_experimental_enable_fixed_dispatcher_for_multi_values=on;.

      • Vous ne pouvez pas écrire de données dans des colonnes de type tableau.

      • Les tableaux dans la fonction unnest doivent être explicitement convertis (cast) vers les types tableau des colonnes correspondantes.

      Exemple :

      BEGIN;
      CREATE TABLE test_insert_multiline (
          pk1 int8,
          col1 float4,
          PRIMARY KEY (pk1)
      );
      COMMIT;
      
      -- A Fixed Plan is supported.
      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;
      
      -- The ARRAY in the unnest function is not explicitly cast. A Fixed Plan is not supported.
      INSERT INTO test_insert_multiline
      SELECT
          unnest(ARRAY[1, 2, 3]),
          unnest(ARRAY[1.11, 2.222, 3])
      ON CONFLICT
          DO NOTHING;
      
      -- The first column is of the int8 type, so the array should be cast to int8[].
      -- In this example, it is cast to int4[], so a Fixed Plan is not supported.
      INSERT INTO test_insert_multiline
      SELECT
          unnest(ARRAY[1, 2, 3]::int4[]),
          unnest(ARRAY[1.11, 2.222, 3]::float4[])
      ON CONFLICT
          DO NOTHING;
  • Scénarios de mise à jour partielle

    Hologres prend en charge la mise à jour de colonnes spécifiques d'une table à l'aide de la clé primaire. Un plan fixe peut également être utilisé pour les mises à jour partielles si les conditions suivantes sont remplies :

    • Le nombre et l'ordre des colonnes dans la liste INSERT doivent correspondre à ceux de la liste UPDATE.

    • La mise à jour doit utiliser le format col = excluded.col.

  • UPSERT conditionnel

    Pour gérer les données amont arrivant dans le désordre pour les lignes partageant la même clé primaire, Hologres propose une fonctionnalité similaire à l'opération CheckAndPut de HBase. Vous pouvez utiliser un Fixed Plan pour les instructions INSERT ou UPDATE avec une clause conditionnelle si les conditions suivantes sont remplies :

    • Cette fonctionnalité est prise en charge pour les insertions de ligne unique. Pour les insertions multi-lignes, vous devez définir le paramètre GUC set hg_experimental_enable_fixed_dispatcher_for_multi_values=on;.

    • La clause WHERE ne doit contenir qu'une seule colonne non-PK, et l'opérateur de comparaison doit être l'un des suivants : =, <>, >, >=, <, <=, IS NULL, or IS NOT NULL. Vous pouvez utiliser la fonction coalesce sur cette colonne non-PK.

    Exemple :

    BEGIN;
    CREATE TABLE test_check_and_insert (
        pk INT,
        col INT,
        scn INT,
        PRIMARY KEY (pk)
    );
    COMMIT;
    
    -- A Fixed Plan is supported.
    -- Compare the existing column value with a constant.
    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;
    
    -- Compare the existing column value with the new value being inserted.
    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;
    
    -- If the existing value might be NULL, use 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;
    
    -- A Fixed Plan is supported.
    SET hg_experimental_enable_fixed_dispatcher_for_multi_values = ON;
    
    -- Compare the existing column value with a constant.
    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;
    
    -- The unnest syntax is also supported.
    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;
  • Colonnes par défaut

    Vous pouvez utiliser un Fixed Plan pour écrire dans une table contenant une colonne avec une valeur DEFAULT si les conditions suivantes sont remplies :

    • Cette fonctionnalité est prise en charge pour les insertions de ligne unique. Pour les insertions multi-lignes, votre instance Hologres doit être en version V1.1.36 ou ultérieure. Si votre instance utilise une version antérieure, effectuez une mise à niveau. Vous devez également définir le paramètre GUC set hg_experimental_enable_fixed_dispatcher_for_multi_values=on; .

    • Hologres V1.3 et les versions ultérieures prennent en charge le Fixed Plan pour la clause Insert on conflict sur les tables disposant d'une colonne Default. Dans les instances de versions antérieures, le Fixed Plan n'est pas pris en charge pour la clause Insert on conflict sur les tables disposant d'une colonne Default.

    Exemple :

    BEGIN;
    CREATE TABLE test_insert_default (
        pk1 INT,
        col1 INT DEFAULT 99,
        PRIMARY KEY (pk1)
    );
    COMMIT;
    
    -- A Fixed Plan is supported.
    INSERT INTO test_insert_default (pk1)
        VALUES (1);
    
    -- This requires Hologres V1.1.36 or later.
    SET hg_experimental_enable_fixed_dispatcher_for_multi_values = ON;
    
    INSERT INTO test_insert_default (pk1)
        VALUES (1), (2), (3);
  • Colonnes SERIAL

    Vous pouvez utiliser un Fixed Plan pour les écritures de ligne unique ou multi-lignes dans une table dotée d'une colonne SERIAL à incrémentation automatique si les conditions suivantes sont remplies :

    • Vous devez définir le paramètre GUC set hg_experimental_enable_fixed_dispatcher_autofill_series=on;. Dans Hologres V1.3.25 et les versions ultérieures, la valeur par défaut de ce paramètre est on.

    • Pour les insertions multi-lignes, vous devez également définir le paramètre GUC set hg_experimental_enable_fixed_dispatcher_for_multi_values=on;.

    Exemple :

    BEGIN;
    CREATE TABLE test_insert_serial (
        pk1 INT,
        col1 SERIAL,
        PRIMARY KEY (pk1)
    );
    COMMIT;
    
    -- A Fixed Plan is supported.
    SET hg_experimental_enable_fixed_dispatcher_autofill_series = ON;
    
    INSERT INTO test_insert_serial (pk1)
        VALUES (1);
    
    -- A Fixed Plan is supported.
    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);

Scénarios de mise à jour

  • Instruction UPDATE

    Une instruction UPDATE comportant les clauses suivantes peut utiliser un fixed plan.

    SET hg_experimental_enable_fixed_dispatcher_for_update = ON;
    
    UPDATE TABLE SET col1 = ?,col2 = ? WHERE pk1 = ? AND pk2 = ?;
  • Remarques d'utilisation

    Une instruction UPDATE peut utiliser un fixed plan si les conditions suivantes sont remplies :

    • Vous pouvez mettre à jour des tables internes et des tables partitionnées enfants, mais pas des tables externes ou des tables partitionnées parentes. La table doit disposer d'une clé primaire (PK).

    • Vous devez exécuter la commande SET hg_experimental_enable_fixed_dispatcher_for_update = ON;. À partir de Hologres V1.3.25, ce paramètre est obsolète. Les instructions UPDATE éligibles utilisent automatiquement un fixed plan. Toutefois, pour mettre à jour plusieurs lignes simultanément, vous devez exécuter la commande SET hg_experimental_enable_fixed_dispatcher_for_multi_values = ON;.

    • Les colonnes spécifiées dans la clause SET ne peuvent pas être des colonnes de clé primaire.

    • La clause WHERE doit spécifier toutes les colonnes de clé primaire. Dans Hologres V1.3 et les versions ultérieures, la dernière condition de la clause WHERE peut porter sur une colonne non-clé primaire et utiliser les opérateurs de comparaison =, <>, >, >=, <, <=, IS NULL, and IS NOT NULL ou la fonction coalesce.

    • Vous pouvez utiliser pk in (?,?,?) or pk = ANY(...) pour mettre à jour plusieurs lignes dans une seule instruction. Par exemple, pk1 in (1,2) and pk2 = any('{3,4}') and pk3 = 5 met à jour les quatre lignes : (1,3,5), (1,4,5), (2,3,5), and (2,4,5).

    • Chaque colonne de la clause WHERE ne peut avoir qu'une seule condition. Les conditions identiques sont traitées comme une seule condition.

    Exemples :

    BEGIN;
    CREATE TABLE test_update (
        pk1 INT,
        pk2 INT,
        col1 INT,
        col2 INT,
        PRIMARY KEY (pk1, pk2)
    );
    COMMIT;
    
    -- Fixed plan supported.
    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 supported.
    SET hg_experimental_enable_fixed_dispatcher_for_update = ON;
    
    UPDATE
        test_update
    SET
        col1 = 1
    WHERE
        pk1 = 3
        AND pk2 = 4;
    
    -- Fixed plan supported (Hologres V1.3+, WHERE clause with a non-primary key column).
    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 supported (Hologres V1.3+, WHERE clause with a non-primary key column and 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 supported.
    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 supported (Hologres V1.3+, WHERE clause with a non-primary key column).
    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;
    
    -- Fixed plan not supported (multiple conditions on pk1).
    UPDATE
        test_update
    SET
        col1 = 1,
        col2 = 2
    WHERE
        pk1 = 3
        AND pk1 = 4;
    
    -- Fixed plan not supported (multiple conditions on pk1).
    UPDATE
        test_update
    SET
        col1 = 1,
        col2 = 2
    WHERE
        pk1 IN (1, 2)
        AND pk1 = 1;
    
    -- Fixed plan supported (multiple identical conditions on 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;

Scénarios de suppression

  • Instruction DELETE

    L'instruction suivante montre comment utiliser un fixed plan pour une opération DELETE :

    SET hg_experimental_enable_fixed_dispatcher_for_delete = ON;
    
    DELETE FROM TABLE
    WHERE pk1 = ?
        AND pk2 = ?
        AND pk3 = ?;
  • Remarques d'utilisation

    Une opération DELETE peut utiliser un fixed plan si elle respecte les conditions suivantes :

    • L'opération doit cibler une table interne ou une table enfant, et non une table externe ou une table partitionnée parente. La table doit également disposer d'une clé primaire (PK).

    • Vous devez définir le paramètre GUC hg_experimental_enable_fixed_dispatcher_for_delete=on;. Dans Hologres V1.3.25 et les versions ultérieures, ce paramètre est obsolète. Les instructions DELETE éligibles utilisent un fixed plan par défaut. Toutefois, pour supprimer plusieurs lignes, vous devez exécuter la commande set hg_experimental_enable_fixed_dispatcher_for_multi_values =on.

    • La clause WHERE doit spécifier des conditions pour toutes les colonnes de clé primaire. À partir de Hologres V1.3, la dernière condition de la clause WHERE peut s'appliquer à un champ non-clé primaire, qui prend en charge les opérateurs de comparaison =, <>, >, >=, <, <=, IS NULL, and IS NOT NULL, ainsi que la fonction coalesce.

    • Vous pouvez utiliser pk in (?,?,?) or pk = ANY() pour supprimer plusieurs lignes en une seule opération. Par exemple, pk1 in (1,2) and pk2 = any('{3,4}') and pk3 = 5 supprime les quatre lignes : (1,3,5), (1,4,5), (2,3,5), and (2,4,5).

    • Chaque colonne ne peut avoir qu'une seule condition dans la clause WHERE. Les conditions en double sont traitées comme une seule condition.

    Exemple :

    BEGIN;
    CREATE TABLE test_delete (
        pk1 INT,
        pk2 INT,
        col1 INT,
        col2 INT,
        PRIMARY KEY (pk1, pk2)
    );
    COMMIT;
    
    -- This DELETE statement uses a fixed plan. For more scenarios, see the examples for the UPDATE statement.
    SET hg_experimental_enable_fixed_dispatcher_for_delete = ON;
    
    DELETE FROM test_delete
    WHERE pk1 = 1
        AND pk2 = 2;
    

Scénarios SELECT

  • Instructions SELECT

    Un fixed plan est pris en charge pour les instructions SELECT contenant des clauses spécifiques.

    SELECT
        col1,
        col2,
        col3,
    ...
    FROM
        TABLE
    WHERE
        pk1 = ?
        AND pk2 = ?
        AND pk3 = ?;
    
    • La requête doit cibler une table interne, et non une table externe.

    • La requête doit cibler une table partitionnée enfant, et non une table partitionnée parente.

    • La table doit disposer d'une clé primaire (PK).

  • Scénarios de requête ponctuelle (clé/valeur)

    Les conditions suivantes s'appliquent aux requêtes ponctuelles utilisant un fixed plan.

    • La clause WHERE doit contenir toutes les colonnes de la clé primaire, et uniquement celles-ci.

    • Vous pouvez utiliser pk in (?,?,?) or pk = ANY() pour interroger plusieurs lignes simultanément. Par exemple, pk1 in (1,2) and pk2 = any('{3,4}') and pk3 = 5 interroge quatre lignes : (1,3,5),(1,4,5),(2,3,5),(2,4,5).

    • Chaque colonne ne peut avoir qu'une seule condition. Les conditions en double sont traitées comme une seule.

    • Si une clause LIMIT est incluse, sa valeur doit être >0.

    Exemple :

    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;
    
    --A fixed plan is supported for this query.
    SELECT * FROM test_select WHERE pk1 = 1 AND pk2 = 2;
  • Scénarios PrefixScan

    • Clauses PrefixScan

      Un PrefixScan s'applique aux requêtes sur des tables dotées d'une clé primaire composite. Ces requêtes utilisent le principe de correspondance du préfixe le plus à gauche pour filtrer sur un préfixe des colonnes de clé primaire. Le code suivant présente des exemples de telles clauses :

      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 < ?;--From Hologres V1.1.48, the last column of the PK prefix can be a range condition.
      SELECT col1,col2,col3,... FROM TABLE WHERE pk1 = ? AND pk2 BETWEEN ? AND ?;--From Hologres V1.1.48, the last column of the PK prefix can be a range condition.                                
    • Utilisation de PrefixScan

      Les conditions suivantes doivent être remplies pour utiliser PrefixScan :

      • Le paramètre GUC hg_experimental_enable_fixed_dispatcher_for_scan=on; doit être défini et l'instance Hologres doit être en version V1.3.35 ou ultérieure.

      • La table doit disposer d'une clé de distribution et la clause WHERE doit inclure toutes les colonnes de la clé de distribution.

      • La clause WHERE ne peut contenir qu'un préfixe de la clé primaire. Dans Hologres V1.1.48 et les versions ultérieures, une condition de plage (avec une borne supérieure et inférieure) peut également être spécifiée pour la dernière colonne du préfixe de clé primaire.

        Remarque

        Définition d'un préfixe : Si une clé primaire est (pk1,pk2,pk3), alors (pk1) et (pk1,pk2) en sont des préfixes.

      • Seules les tables orientées ligne et hybrides ligne-colonne prennent en charge PrefixScan.

      • Chaque colonne ne peut avoir qu'une seule condition. Les conditions en double sont traitées comme une seule.

      • Si une clause LIMIT est incluse, sa valeur doit être > 0.

      Remarque

      Un PrefixScan renvoie toutes les lignes de résultat en une seule fois. Si la taille totale en octets des résultats dépasse la valeur de hg_experimental_fixed_scan_bytesize_limit, une erreur est renvoyée : scan result size larger than fixed scan size limit. Vous pouvez configurer le paramètre hg_experimental_fixed_scan_bytesize_limit avec une valeur adaptée à votre scénario. La valeur par défaut est 1 048 576 (1 Mo).

      Par exemple, supposons que la clé primaire d'une table soit (pk1,pk2,pk3,pk4) et que sa clé de distribution soit 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;
      
      --Does not include all distribution key columns. A fixed plan cannot be used.
      SELECT * FROM test_select_prefix WHERE pk1 = ? AND pk2 = ?;
      --Not a prefix of the primary key. A fixed plan cannot be used.
      SELECT * FROM test_select_prefix WHERE pk1 = ? AND pk3 = ?;
      
      --A fixed plan can be used.
      SET hg_experimental_enable_fixed_dispatcher_for_scan = ON;
      
      SELECT * FROM test_select_prefix WHERE pk1 = ? AND pk2 = ? AND pk3 = ?;
      

      Vous pouvez utiliser pk in (?,?,?) ou pk = ANY() pour interroger plusieurs lignes simultanément, comme illustré dans les exemples suivants.

      pk1 IN (1,2) AND pk2 = 3 --Equivalent to scanning two key groups: (1,3) and (2,3).
      pk2 =any('{3,4}') AND pk1 IN (1,2) --Equivalent to scanning four key groups: (1,3), (1,4), (2,3), and (2,4).
    • Exemple d'utilisation

      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);
      
      --A fixed plan is supported.
      SET hg_experimental_enable_fixed_dispatcher_for_scan = ON;
      
      SELECT * FROM test_scan WHERE pk1 = 1 AND pk2 = 2;
      
      --A fixed plan is supported.
      SET hg_experimental_enable_fixed_dispatcher_for_scan = ON;
      
      SELECT * FROM test_scan WHERE pk1 = 1 AND pk2 IN (2, 3);
      
      --A fixed plan is supported.
      SET hg_experimental_enable_fixed_dispatcher_for_scan = ON;
      
      SELECT * FROM test_scan WHERE pk1 = ANY ('{3,4}') AND pk2 IN (2, 3);
      
      --A fixed plan is supported. The last column of the PK is a range condition. Requires Hologres V1.1.48 or later.
      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;
      
      --A fixed plan is supported. The last column of the PK is a range condition. Requires Hologres V1.1.48 or later.
      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;
      
      --Does not include all distribution key columns. A fixed plan is not supported.
      SELECT * FROM test_scan WHERE pk1 = 1;
      
      --Does not match a primary key prefix. A fixed plan is not supported.
      SELECT * FROM test_scan WHERE pk2 = 2;
  • Scénarios de pagination

    Dans Hologres V3.2 et les versions ultérieures, le fixed plan prend en charge les requêtes PrefixScan utilisant la pagination.

    Remarque
    • Par défaut, les résultats d'un PrefixScan sont triés par ordre croissant de la clé primaire. Dans l'exemple SQL suivant, un PrefixScan sur pk1 et pk2 renvoie des résultats triés par ordre croissant de pk3.

    • Pour spécifier l'ordre de tri, vous pouvez définir l'ordre des colonnes dans la clustering key et définir le paramètre GUC correspondant dans votre requête, ce qui trie les résultats selon la clustering key. Les colonnes de la clustering key doivent être identiques aux colonnes de la clé primaire. Dans l'exemple SQL suivant, pour trier les résultats par ordre décroissant, vous pouvez définir la dernière colonne de la clustering key sur pk3:desc.

    • Ordre croissant

      -- Create a table.
      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 data.
      INSERT INTO test_scan VALUES (1,2,3,4),(1,2,5,6),(1,2,7,8);
      
      -- `offset + limit` is supported. Based on PrefixScan, this query returns a specified number of rows starting from a specified offset.
      SET hg_experimental_enable_fixed_dispatcher_for_scan = on;
      -- By default, the results are sorted in ascending order of pk3.
      SELECT * FROM test_scan WHERE pk1 = 1 AND pk2 = 2 OFFSET 1 limit 2;
    • Ordre décroissant

      -- Create a table.
      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 data.
      INSERT INTO test_scan VALUES (1,2,3,4),(1,2,5,6),(1,2,7,8);
      
      -- Enable both of the following GUC parameters to sort the results in descending order of 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;

Scénarios d'utilisation de COPY

À partir de la version V1.3.17 de Hologres, l'instruction COPY peut utiliser un plan fixe, une fonctionnalité appelée Fixed Copy. Pour comparer les instructions COPY et Fixed Copy, consultez la rubrique Bonnes pratiques pour l'écriture par lots.

Pour plus d'informations sur les paramètres de Fixed Copy, consultez la section COPY. Voici un exemple :

COPY table_name (column0, column1, column2)
FROM
    STDIN WITH (
        format BINARY,
        stream_mode TRUE,
        on_conflict UPDATE);

Lorsque vous omettez des colonnes dans une instruction COPY, le comportement est le suivant :

  • Si l'instruction COPY spécifie un sous-ensemble des colonnes de la table, elle effectue une mise à jour partielle. Par exemple :

    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);
    
    -- The COPY statement above is equivalent to the following INSERT INTO statement:
    INSERT INTO t0 (id, name)
        VALUES (?, ?)
    ON CONFLICT (id)
        DO UPDATE SET id = excluded.id, name = excluded.name;
  • Si les colonnes omises possèdent une valeur par défaut, l'instruction COPY se comporte comme suit :

    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);
    
    -- The COPY statement above is equivalent to the following INSERT INTO statement:
    -- If the ID does not exist, a new row is inserted, and the age column is set to its default value.
    -- If the ID already exists, the row is updated, and the age column remains unchanged.
    INSERT INTO t0 (id, name, age)
        VALUES (?, ?, DEFAULT)
    ON CONFLICT (id)
        DO UPDATE SET id = excluded.id, name = excluded.name;
    

Expressions dans les plans fixes

À partir de la version V3.2 de Hologres, la fonctionnalité Fixed Plan prend en charge les expressions dans les instructions SQL. Pour plus d'informations sur les expressions dans PostgreSQL, consultez la documentation Expressions. Les scénarios pris en charge incluent :

  • Instructions INSERT :

    • Clause VALUES

    • Clause INSERT ON CONFLICT DO UPDATE

    • Condition de filtre dans la clause INSERT ON CONFLICT WHERE

    • Clause RETURNING

  • Instructions SELECT :

    Liste SELECT

Limites

  • Seules les expressions et fonctions scalaires sont prises en charge. Les fonctions d'agrégation, les fonctions de fenêtrage et les sous-requêtes ne sont pas prises en charge.

  • Pour les instructions INSERT, les expressions et fonctions utilisées dans les clauses autres que la clause VALUES doivent être prises en charge par HQE.

  • Pour les instructions SELECT, Fixed Plan prend uniquement en charge les expressions et fonctions IMMUTABLE qui acceptent un argument constant.

  • Pour utiliser cette fonctionnalité, vous devez activer le paramètre suivant :

    -- Enable at the session level
    SET hg_experimental_enable_fixed_plan_expression = on;
    
    -- Enable at the database level
    ALTER DATABASE <db_name> SET hg_experimental_enable_fixed_plan_expression = on;

Exemples

  • Utilisation d'expressions dans les quatre clauses prises en charge d'une instruction INSERT

    -- Create a table.
    CREATE TABLE test_t (
        id INT PRIMARY KEY,
        col INT,
        ts TIMESTAMP
    )
    WITH (
        orientation = 'row',
        distribution_key = 'id'
    );
    
    -- Enable the GUC parameter.
    SET hg_experimental_enable_fixed_plan_expression = ON;
    
    -- Use an expression in the VALUES clause.
    INSERT INTO test_t VALUES (1, 1, now());
    
    -- Use an expression in the ON CONFLICT DO UPDATE clause.
    INSERT INTO test_t AS old 
        VALUES (1, 1, now())
        ON CONFLICT (id) 
        DO UPDATE SET col = excluded.col + old.col, ts = excluded.ts;
    
    -- Use an expression in the ON CONFLICT WHERE clause.
    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;
    
    -- Use an expression in the RETURNING clause.
    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;
  • Utilisation d'expressions dans la liste SELECT d'une instruction SELECT

    • Requête ponctuelle utilisant une clé primaire complète : cet exemple extrait la valeur d'une clé d'une colonne JSONB.

      -- Create a table.
      CREATE TABLE test_t (
          id int PRIMARY KEY,
          ts TIMESTAMP NOT NULL,
          col JSONB
      )
      WITH (
          orientation = 'row',
          distribution_key = 'id'
      );
      
      -- Use expressions in the SELECT list. JSONB operators are supported.
      SELECT
          (col ->> 'b')::int + (col ->> 'a')::int,
          date_trunc('day', ts)
      FROM
          test_t
      WHERE
          id = 1;
    • PrefixScan utilisant un préfixe de clé primaire.

      -- Create a table.
      CREATE TABLE test_t (
          id INT,
          ts TIMESTAMP NOT NULL,
          col JSONB,
          PRIMARY KEY (id, ts)
      )
      WITH (
          orientation = 'row',
          distribution_key = 'id'
      );
      
      -- Enable the GUC parameter.
      SET hg_experimental_enable_fixed_dispatcher_for_scan = TRUE;
      
      -- Use expressions in the SELECT list.
      SELECT
          (col ->> 'b')::int + (col ->> 'a')::int,
          date_trunc('day', ts)
      FROM
          test_t
      WHERE
          id = 1;
  • Une instruction SELECT ne peut pas être optimisée par Fixed Plan si elle contient des fonctions non IMMUTABLE ou des fonctions qui n'acceptent pas d'argument constant.

    -- Create a table.
    CREATE TABLE test_t (
        id INT PRIMARY KEY,
        ts TIMESTAMP NOT NULL,
        col JSONB
    )
    WITH (
        orientation = 'row',
        distribution_key = 'id'
    );
    
    -- The random() function is not immutable and is not supported by Fixed Plan.
    SELECT
        id + random()
    FROM
        test_t
    WHERE
        id = 1;
    
    -- The toString function does not accept a constant argument and is not supported by Fixed Plan.
    SELECT
        toString (id)
    FROM
        test_t
    WHERE
        id = 1;

Vérification d'un plan fixe

  • Dans la console, les instructions INSERT, UPDATE et DELETE exécutées à l'aide d'un plan fixe apparaissent comme de type SDK dans le panneau Real-time Import (RPS). Nous vous recommandons d'utiliser des plans fixes pour ces opérations d'écriture en temps réel afin d'améliorer l'efficacité des mises à jour de données.RPS

  • Pour afficher le plan d'exécution SQL, exécutez une instruction EXPLAIN. Si le plan d'exécution renvoyé contient FixedXXXNode, un plan fixe a été déclenché, comme illustré dans la figure suivante. Si le plan d'exécution ne contient pas FixedXXXNode, vérifiez les conditions de prise en charge décrites dans les sections précédentes et assurez-vous que votre instruction respecte les exigences.验证fixedplan

Optimisation des performances

Si vous devez encore optimiser les performances avec un plan fixe activé, vous pouvez utiliser les méthodes suivantes.

  • Analysez le plan d'exécution pour identifier les goulots d'étranglement. Exécutez EXPLAIN sur une instruction SQL pour visualiser le temps consommé à chaque étape et localiser les goulots d'étranglement.

  • Les versions 1.1.49 et ultérieures de Hologres sont optimisées pour les requêtes ponctuelles utilisant un plan fixe, ce qui améliore le débit de plus de 30 % dans les scénarios à grande échelle. Pour bénéficier de cette amélioration, mettez à niveau votre instance vers la version V1.1.49 ou une version ultérieure.

  • Utilisez le regroupement côté client avec une taille de lot de 512 ou un multiple de 512. Holo Client gère automatiquement le regroupement.

FAQ

  • Symptôme : Lorsque vous tentez de vous connecter à Hologres, l'erreur suivante se produit : role/database does not exist.

    • Cause : L'utilisateur ou la base de données spécifié(e) n'existe pas.

    • Solution : Vérifiez vos informations de connexion et assurez-vous que le nom d'utilisateur et le nom de la base de données sont corrects.

      Connectez-vous à la console Hologres. Trouvez l'instance cible et cliquez sur Manage dans la colonne Actions. Cliquez sur Database Management. Vous pouvez ensuite vérifier le nom d'utilisateur sur la page Users et le nom de la base de données sur la page Database Authorization.

  • Symptôme : Lors d'une opération d'écriture de données, l'erreur suivante se produit : the requested table name: xxx (id: xx, version: xx) mismatches the version of the table (id: xx, version: xx) from server.

    • Cause : Les métadonnées de la table changent pendant l'opération d'écriture de données (par exemple, une colonne est ajoutée), ce qui modifie la version de la table.

    • Solution : Rétablissez la connexion. Le plan fixe récupère alors les nouvelles métadonnées de la table pour terminer l'opération d'écriture.