Todos os produtos
Search
Central de documentação

Hologres:Acelere a execução de SQL com fixed plans

Última atualização: Jun 30, 2026

O fixed plan é um recurso de otimização do mecanismo de execução exclusivo do Hologres. Este tópico descreve os pré-requisitos e as configurações de parâmetros necessários para que uma instrução SQL seja elegível para um fixed plan.

Informações de contexto

O fixed plan é um método de otimização do mecanismo de execução exclusivo do Hologres. A execução tradicional de SQL envolve vários componentes, como o otimizador, o coordenador, o mecanismo de consulta e o mecanismo de armazenamento. Em contraste, o fixed plan utiliza um caminho direto que ignora o otimizador, o coordenador e partes do mecanismo de consulta para reduzir a sobrecarga de processamento. O frontend fixo conecta-se diretamente ao mecanismo de consulta fixo, melhorando significativamente a eficiência da execução de SQL. Essa otimização fundamental permite gravações em tempo real com alto throughput e consultas com alta concorrência. Para obter mais informações sobre fixed plans, consulte arquitetura do produto.

No Hologres, os fixed plans são usados por padrão nos seguintes cenários:

  • Gravações em tempo real no Hologres usando Flink.

  • Gravações em tempo real no Hologres usando Data Integration do DataWorks.

  • Gravações no Hologres usando Holo Client.

Para outros cenários de gravação, configure suas instruções SQL para usar um fixed plan. Para obter mais informações, consulte as seções a seguir.

Nota

Nesses cenários, o Hologres usa fixed plans por padrão para instruções SQL elegíveis. No entanto, nem todas as instruções SQL nesses cenários são elegíveis.

Parâmetros GUC relacionados

  • Lista de parâmetros GUC

    Os parâmetros a seguir configuram o Fixed Plan. O valor de cada parâmetro pode ser on ou off. Todos os parâmetros estão habilitados por padrão no Holo Client e entram em vigor no nível da sessão.

    Parâmetro

    Descrição

    Padrão

    Histórico de alterações

    hg_experimental_enable_fixed_dispatcher

    Controla a habilitação do recurso de fixed plan para a instância.

    Oferece suporte a fixed plans para operações INSERT, UPDATE, DELETE e PrefixScan de linha única.

    on

    N/A.

    hg_experimental_enable_fixed_dispatcher_for_multi_values

    Controla o uso de fixed plan para operações INSERT de várias linhas.

    Nota

    A atomicidade não é garantida. Para inserções de várias linhas, uma operação bem-sucedida significa que todas as linhas foram inseridas. Se ocorrer um erro, o sistema retornará uma única mensagem que pode indicar uma inserção parcial ou uma falha completa. A aplicação cliente é responsável por tentar novamente quaisquer linhas com falha.

    on

    A partir do Hologres V1.3.35, este parâmetro GUC permite que operações INSERT, UPDATE e DELETE de várias linhas usem fixed plans.

    hg_experimental_enable_fixed_dispatcher_autofill_series

    Oferece suporte a fixed plans para gravações em tabelas que contêm colunas do tipo SERIAL. Recomendamos ative este parâmetro no nível da sessão.

    on

    O valor padrão foi alterado para on no Hologres V1.3.25.

    hg_experimental_enable_fixed_dispatcher_for_update

    Oferece suporte a fixed plans para operações UPDATE. Recomendamos ative este parâmetro no nível da sessão.

    off

    A partir do Hologres V1.3.25, o parâmetro hg_experimental_enable_fixed_dispatcher_for_update foi descontinuado. Instruções UPDATE elegíveis usam um fixed plan por padrão. No entanto, para atualize várias linhas, configure set hg_experimental_enable_fixed_dispatcher_for_multi_values = on.

    hg_experimental_enable_fixed_dispatcher_for_delete

    Oferece suporte a fixed plans para operações DELETE. Recomendamos ative este parâmetro no nível da sessão.

    off

    A partir do Hologres V1.3.25, o parâmetro hg_experimental_enable_fixed_dispatcher_for_delete foi descontinuado. Instruções DELETE elegíveis usam um fixed plan por padrão. No entanto, para exclua várias linhas, configure set hg_experimental_enable_fixed_dispatcher_for_multi_values = on.

    hg_experimental_enable_fixed_dispatcher_for_scan

    Oferece suporte a fixed plans para consultas PrefixScan.

    Nota

    Uma consulta PrefixScan é uma consulta em uma tabela com chave primária composta, onde as condições especifique apenas as colunas iniciais da chave primária. Atualmente, não há suporte para fixed plans em consultas PrefixScan em tabelas orientadas a colunas.

    off

    Recomenda-se o Hologres V1.3.35 ou posterior.

    hg_experimental_enable_bhclient_cache_on_session

    Controla o modo de cache. Dois modos estão disponíveis.

    • on: Usa o modo cached on session.

    • off: Usa o modo cached on fe.

    Nota

    A lista a seguir compara os modos cached on session e cached on fe.

    • cached on session: Cada sessão tem seu próprio writer e reader. Este modo oferece maior throughput por sessão, mas possui inicialização mais lenta, pois o writer e o reader exigem inicialização antes da primeira operação em cada tabela.

    • cached on fe: Todas as sessões em um nó FE compartilham writers e readers. Writers e readers não são fechados quando uma sessão termina, o que elimina o tempo de inicialização.

    off

    N/A.

    hg_experimental_disable_fixed_planner_conflict_pk_check

    Controla se a na sintaxe INSERT INTO <table_name> VALUES (...) ON CONFLICT(<column>) pode ser uma coluna que não seja chave primária.

    • false: Não suportado.

    • true: Suportado.

      Nota

      Se este parâmetro GUC estiver definido como true, você poderá especifique uma coluna que não seja chave primária. No entanto, a instrução INSERT ON CONFLICT ainda processará os dados com base na duplicação da chave primária, como se ON CONFLICT(pk) tivesse sido especificado.

    false

    • Nas versões do Hologres de V1.3 a V2.1.28, a coluna especificada em ON CONFLICT(<column>) deve ser uma coluna de chave primária.

    • Este parâmetro está disponível apenas no Hologres V2.1.29 e versões posteriores V2.1.x. Ele controla se a coluna em ON CONFLICT(<column>) pode ser uma chave não primária. Este parâmetro foi removido na V3.0 e posteriores, e nenhuma configuração é necessária.

  • Uso de parâmetros GUC

    • Verificar a configuração de um parâmetro GUC

      Use o comando SHOW para verificar a configuração de um parâmetro GUC.

      SHOW <GUC_name>;

      Exemplo:

      -- Check whether the fixed plan feature is enabled at the instance level.
      SHOW hg_experimental_enable_fixed_dispatcher;
    • Definir um parâmetro GUC

      • Definir um parâmetro GUC no nível da sessão

        Use o comando SET para configure um parâmetro GUC no nível da sessão. A configuração aplica-se apenas à sessão atual e é descartada quando ela é fechada. Recomendamos incluir este comando antes da sua instrução SQL.

        SET <GUC_name> = <values>;

        GUC_name especifique o nome do parâmetro GUC e values especifique o valor do parâmetro.

        Exemplo:

        -- Enable fixed plan for multi-row INSERT ON CONFLICT statements.
        SET hg_experimental_enable_fixed_dispatcher_for_multi_values = on;
      • Definir um parâmetro GUC no nível do banco de dados

        Use o comando ALTER DATABASE ... SET ... para defina um parâmetro GUC no nível do banco de dados. A configuração entra em vigor para todo o banco de dados. Para aplicar a alteração à sessão atual, reconecte-se. Esta configuração não se aplica a novos bancos de dados; configure-a manualmente para cada um.

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

        db_name especifique o nome do banco de dados, GUC_name especifique o nome do parâmetro GUC e values especifique o valor do parâmetro.

        Exemplo:

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

Requisitos de tipo de dados

  • As colunas de uma tabela não podem ser do tipo MONEY ou MONEY ARRAY.

  • Os seguintes tipos de dados são suportados para colunas em operações DML (INSERT, UPDATE e DELETE) e SELECT. Para instruções SELECT, este requisito aplica-se tanto às colunas de destino quanto às colunas na cláusula WHERE.

    • BOOLEAN (alias: BOOL)

    • SMALLINT

    • INTEGER (aliases: INT, INT4)

    • BIGINT (alias: INT8)

    • FLOAT (alias: FLOAT4)

    • DOUBLE PRECISION (alias: FLOAT8)

    • CHAR(n)

    • VARCHAR(n) (No Hologres V1.1.79 e posterior, VARCHAR pode usar Fixed Plan.)

    • BYTEA

    • JSON e JSONB

    • TEXT (alias: VARCHAR)

    • TIMESTAMP WITH TIME ZONE (alias: TIMESTAMPTZ)

    • DATE

    • TIMESTAMP

    • DECIMAL (alias: NUMERIC)

    • ROARINGBITMAP

    • TIME (suportado no Hologres V2.2 e posterior)

    • TIMETZ (suportado no Hologres V2.2 e posterior)

    • Tipos de array

      • boolean[]

      • smallint[]

      • int4[]

      • int8[]

      • float4[]

      • float8[]

      • char(n)[]

      • varchar(n)[]

      • text[]

Cenários de inserção

A partir do Hologres V3.2, você pode usar a cláusula RETURNING em uma instrução INSERT que utiliza um Fixed Plan para gravar em uma tabela com chave primária.

  • Instrução Insert

    Um Fixed Plan pode ser usado com as seguintes instruções INSERT.

    -- 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;
    Nota
    • Use a instrução INSERT para gravar dados em tabelas internas, mas não em tabelas externas.

    • Use a instrução INSERT para gravar dados em uma tabela particionada. O Hologres V1.3 e posterior também oferece suporte à gravação em uma tabela particionada pai.

    • A palavra-chave RETURNING não é suportada em instruções INSERT nas versões do Hologres anteriores à V3.2. Ela é suportada no Hologres V3.2 e posterior.

  • INSERT ON CONFLICT de linha única

    • Os seguintes cenários são suportados:

      • Uma instrução INSERT sem uma cláusula ON CONFLICT.

      • Uma instrução INSERT com uma cláusula ON CONFLICT DO NOTHING.

      • Uma instrução INSERT com uma cláusula ON CONFLICT DO UPDATE. Para usar um Fixed Plan, atualize todas as colunas que não sejam chave primária (non-PK) especificadas na instrução INSERT. Opcionalmente, atualize as colunas de chave primária (PK). A atualização deve usar o formato col = excluded.col. No Hologres V1.3 e posterior, é possível atualize um subconjunto de colunas non-PK, mas o formato col = excluded.col ainda é obrigatório.

    • Exemplo:

      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 de várias linhas

    • Para operações INSERT ON CONFLICT de várias linhas, use a seguinte sintaxe:

      SET hg_experimental_enable_fixed_dispatcher_for_multi_values = ON;
      
      INSERT INTO TABLE (col1, col2, col3..)
          VALUES (?, ?, ?..), (?, ?, ?..)
      ON CONFLICT xxx;
      • Defina o parâmetro GUC hg_experimental_enable_fixed_dispatcher_for_multi_values = on;. No Hologres V1.3.35 e posterior, este parâmetro é definido como on por padrão.

      • Essas operações não garantem atomicidade. Uma operação bem-sucedida grava todas as linhas. Se ocorrer um erro, algumas ou nenhuma das linhas pode ter sido gravada.

    • Alternativamente, use a seguinte sintaxe para gravar várias linhas:

      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;
      • Defina o parâmetro GUC hg_experimental_enable_fixed_dispatcher_for_multi_values=on;.

      • Não é possível gravar dados em colunas de um tipo de array.

      • Os arrays na função unnest devem ser convertidos explicitamente para os tipos de array das colunas correspondentes.

      Exemplo:

      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;
  • Cenários de atualização parcial

    O Hologres oferece suporte à atualização de colunas específicas de uma tabela usando a chave primária. Um Fixed Plan também pode ser usado para atualizações parciais se as seguintes condições forem atendidas:

    • O número e a ordem das colunas na lista INSERT devem corresponder aos da lista UPDATE.

    • A atualização deve usar o formato col = excluded.col.

  • UPSERT condicional

    Para lidar com dados upstream fora de ordem para linhas com a mesma chave primária, o Hologres fornece um recurso semelhante à operação CheckAndPut do HBase. Use um Fixed Plan para instruções INSERT ou UPDATE com uma cláusula condicional se as seguintes condições forem atendidas:

    • Este recurso é suportado para inserções de linha única. Para inserções de várias linhas, defina o parâmetro GUC set hg_experimental_enable_fixed_dispatcher_for_multi_values=on;.

    • A cláusula WHERE deve conter apenas uma única coluna non-PK, e o operador de comparação deve ser um dos seguintes: =, <>, >, >=, <, <=, IS NULL ou IS NOT NULL. É possível usar a função coalesce nesta coluna não-PK.

    Exemplo:

    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;
  • Colunas padrão

    Use um Fixed Plan para gravar em uma tabela que contém uma coluna com um valor DEFAULT se as seguintes condições forem atendidas:

    • Este recurso é suportado para inserções de linha única. Para inserções de várias linhas, sua instância do Hologres deve ser V1.1.36 ou posterior. Se sua instância for de uma versão anterior, atualize-a. Defina também o parâmetro GUC set hg_experimental_enable_fixed_dispatcher_for_multi_values=on; .

    • O Hologres V1.3 e versões posteriores oferecem suporte ao Fixed Plan para a cláusula Insert on conflict em tabelas que possuem uma coluna Default. Em instâncias de versões anteriores, o Fixed Plan não é suportado para a cláusula Insert on conflict em tabelas que possuem uma coluna Default.

    Exemplo:

    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);
  • Colunas Serial

    Use um Fixed Plan para gravações de linha única ou várias linhas em uma tabela com uma coluna SERIAL de incremento automático se as seguintes condições forem atendidas:

    • Defina o parâmetro GUC set hg_experimental_enable_fixed_dispatcher_autofill_series=on;. No Hologres V1.3.25 e posterior, o valor padrão deste parâmetro é on.

    • Para inserções de várias linhas, defina também o parâmetro GUC set hg_experimental_enable_fixed_dispatcher_for_multi_values=on;.

    Exemplo:

    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);

Cenários de atualização

  • Instrução UPDATE

    Uma instrução UPDATE com as seguintes cláusulas pode usar um fixed plan.

    SET hg_experimental_enable_fixed_dispatcher_for_update = ON;
    
    UPDATE TABLE SET col1 = ?,col2 = ? WHERE pk1 = ? AND pk2 = ?;
  • Notas de uso

    Uma instrução UPDATE pode usar um fixed plan se as seguintes condições forem atendidas:

    • Atualize tabelas internas e tabelas particionadas filhas, mas não tabelas externas ou tabelas particionadas pai. A tabela deve ter uma chave primária (PK).

    • Execute o comando SET hg_experimental_enable_fixed_dispatcher_for_update = ON;. A partir do Hologres V1.3.25, este parâmetro foi descontinuado. Instruções UPDATE elegíveis usam automaticamente um fixed plan. No entanto, para atualize várias linhas de uma vez, execute o comando SET hg_experimental_enable_fixed_dispatcher_for_multi_values = ON;.

    • As colunas especificadas na cláusula SET não podem ser colunas de chave primária.

    • A cláusula WHERE deve especifique todas as colunas de chave primária. No Hologres V1.3 e posterior, a última condição na cláusula WHERE pode ser em uma coluna que não seja chave primária e pode usar os operadores de comparação =, <>, >, >=, <, <=, IS NULL e IS NOT NULL ou a função coalesce.

    • Use pk in (?,?,?) or pk = ANY(...) para atualize várias linhas em uma única instrução. Por exemplo, pk1 in (1,2) and pk2 = any('{3,4}') and pk3 = 5 atualize as quatro linhas: (1,3,5), (1,4,5), (2,3,5) e (2,4,5).

    • Cada coluna na cláusula WHERE pode ter apenas uma condição. Condições idênticas são tratadas como uma única condição.

    Exemplos:

    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;

Cenários de exclusão

  • Instrução DELETE

    A instrução a seguir mostra como usar um fixed plan para uma operação DELETE:

    SET hg_experimental_enable_fixed_dispatcher_for_delete = ON;
    
    DELETE FROM TABLE
    WHERE pk1 = ?
        AND pk2 = ?
        AND pk3 = ?;
  • Notas de uso

    Uma operação DELETE pode usar um fixed plan se atender às seguintes condições:

    • A operação deve ter como alvo uma tabela interna ou uma tabela filha, não uma tabela externa ou uma tabela particionada pai. A tabela também deve ter uma chave primária (PK).

    • Defina o parâmetro GUC hg_experimental_enable_fixed_dispatcher_for_delete=on;. No Hologres V1.3.25 e posterior, este parâmetro foi descontinuado. Instruções DELETE elegíveis usam um fixed plan por padrão. No entanto, para exclua várias linhas, execute o comando set hg_experimental_enable_fixed_dispatcher_for_multi_values =on.

    • A cláusula WHERE deve especifique condições para todas as colunas de chave primária. A partir do Hologres V1.3, a última condição na cláusula WHERE pode ser aplicada a um campo que não seja chave primária, o que suporta os operadores de comparação =, <>, >, >=, <, <=, IS NULL e IS NOT NULL, bem como a função coalesce.

    • Use pk in (?,?,?) or pk = ANY() para exclua várias linhas em uma única operação. Por exemplo, pk1 in (1,2) and pk2 = any('{3,4}') and pk3 = 5 exclua as quatro linhas: (1,3,5), (1,4,5), (2,3,5) e (2,4,5).

    • Cada coluna pode ter apenas uma condição na cláusula WHERE. Condições duplicadas são tratadas como uma única condição.

    Exemplo:

    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;
    

Cenários SELECT

  • Instruções SELECT

    Um fixed plan é suportado para instruções SELECT que contêm cláusulas específicas.

    SELECT
        col1,
        col2,
        col3,
    ...
    FROM
        TABLE
    WHERE
        pk1 = ?
        AND pk2 = ?
        AND pk3 = ?;
    
    • A consulta deve ter como alvo uma tabela interna, não uma tabela externa.

    • A consulta deve ter como alvo uma tabela particionada filha, não uma tabela particionada pai.

    • A tabela deve ter uma chave primária (PK).

  • Cenários de consulta pontual (chave/valor)

    As seguintes condições aplicam-se a consultas pontuais que usam um fixed plan.

    • A cláusula WHERE deve conter todas e apenas as colunas da chave primária.

    • Use pk in (?,?,?) or pk = ANY() para consultar várias linhas de uma vez. Por exemplo, pk1 in (1,2) and pk2 = any('{3,4}') and pk3 = 5 consulta quatro linhas: (1,3,5),(1,4,5),(2,3,5),(2,4,5).

    • Cada coluna pode ter apenas uma condição. Condições duplicadas são tratadas como uma só.

    • Se uma cláusula LIMIT for incluída, seu valor deve ser >0.

    Exemplo:

    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;
  • Cenários PrefixScan

    • Cláusulas PrefixScan

      Um PrefixScan aplica-se a consultas em tabelas com uma chave primária composta. Essas consultas usam o princípio de correspondência de prefixo mais à esquerda para filtrar em um prefixo das colunas da chave primária. O código a seguir mostra exemplos de tais cláusulas:

      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.                                
    • Uso do PrefixScan

      As seguintes condições devem ser atendidas para usar o PrefixScan:

      • O parâmetro GUC hg_experimental_enable_fixed_dispatcher_for_scan=on; deve ser definido, e a instância do Hologres deve ser V1.3.35 ou posterior.

      • A tabela deve ter uma chave de distribuição, e a cláusula WHERE deve incluir todas as colunas da chave de distribuição.

      • A cláusula WHERE pode conter apenas um prefixo da chave primária. No Hologres V1.1.48 e posterior, uma condição de intervalo (com limite superior e inferior) também pode ser especificada para a última coluna do prefixo da chave primária.

        Nota

        Definição de prefixo: Se uma chave primária for (pk1,pk2,pk3), então (pk1) e (pk1,pk2) são seus prefixos.

      • Apenas tabelas orientadas a linhas e tabelas híbridas linha-coluna suportam PrefixScan.

      • Cada coluna pode ter apenas uma condição. Condições duplicadas são tratadas como uma só.

      • Se uma cláusula LIMIT for incluída, seu valor deve ser > 0.

      Nota

      Um PrefixScan retorna todas as linhas de resultado de uma vez. Se o tamanho total em bytes dos resultados exceder o valor de hg_experimental_fixed_scan_bytesize_limit, um erro será retornado: scan result size larger than fixed scan size limit. Configure o parâmetro hg_experimental_fixed_scan_bytesize_limit com um valor adequado ao seu cenário. O valor padrão é 1.048.576 (1 MB).

      Por exemplo, suponha que a chave primária de uma tabela seja (pk1,pk2,pk3,pk4) e sua chave de distribuição seja 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 = ?;
      

      Use pk in (?,?,?) ou pk = ANY() para consultar várias linhas de uma vez, conforme mostrado nos exemplos a seguir.

      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).
    • Exemplo de uso

      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;
  • Cenários de paginação

    No Hologres V3.2 e posterior, o fixed plan oferece suporte a consultas PrefixScan que usam paginação.

    Nota
    • Por padrão, os resultados de um PrefixScan são classificados em ordem crescente da chave primária. No exemplo SQL a seguir, um PrefixScan em pk1 e pk2 retorna resultados classificados em ordem crescente de pk3.

    • Para especifique a ordem de classificação, defina a ordem das colunas na clustering key e defina o parâmetro GUC correspondente em sua consulta, o que classifica os resultados de acordo com a clustering key. As colunas da clustering key devem ser idênticas às colunas da chave primária. No exemplo SQL a seguir, para classificar os resultados em ordem decrescente, defina a última coluna da clustering key como pk3:desc.

    • Ordem crescente

      -- 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;
    • Ordem decrescente

      -- 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;

Cenários COPY

A partir do Hologres V1.3.17, a instrução COPY pode usar um fixed plan, um recurso conhecido como Fixed Copy. Para obter uma comparação entre COPY e Fixed Copy, consulte Melhores práticas para gravação em lote.

Para obter mais informações sobre os parâmetros do Fixed Copy, consulte COPY. Veja a seguir um exemplo:

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

Quando você omite colunas em uma instrução COPY, o comportamento é o seguinte:

  • Se a instrução COPY especifique um subconjunto das colunas da tabela, ela executará uma atualização parcial. Por exemplo:

    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;
  • Se as colunas omitidas tiverem um valor padrão, a instrução COPY se comportará da seguinte maneira:

    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;
    

Expressões no Fixed Plan

A partir do Hologres V3.2, o recurso Fixed Plan oferece suporte a expressões em instruções SQL. Para obter mais informações sobre expressões no PostgreSQL, consulte Expressões. Os cenários suportados incluem:

  • Instruções INSERT:

    • Cláusula VALUES

    • Cláusula INSERT ON CONFLICT DO UPDATE

    • Condição de filtro na cláusula INSERT ON CONFLICT WHERE

    • Cláusula RETURNING

  • Instruções SELECT:

    A lista SELECT

Limitações

  • Apenas expressões e funções escalares são suportadas. Funções de agregação, funções de janela e subconsultas não são suportadas.

  • Para instruções INSERT, expressões e funções usadas em cláusulas diferentes da cláusula VALUES devem ser suportadas pelo HQE.

  • Para instruções SELECT, o Fixed Plan suporta apenas expressões e funções IMMUTABLE que aceitam um argumento constante.

  • Para usar este recurso, ative o seguinte parâmetro:

    -- 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;

Exemplos

  • Uso de expressões nas quatro cláusulas suportadas de uma instrução 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;
  • Uso de expressões na lista SELECT de uma instrução SELECT

    • Consulta pontual usando uma chave primária completa: Este exemplo extrai o valor de uma chave de uma coluna 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 usando um prefixo de chave primária.

      -- 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;
  • Uma instrução SELECT não pode ser otimizada pelo Fixed Plan se contiver funções não IMMUTABLE ou funções que não aceitem um argumento constante.

    -- 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;

Verificação de um fixed plan

  • No console, as instruções INSERT, UPDATE e DELETE executadas usando um fixed plan aparecem como o tipo SDK no painel Real-time Import (RPS). Recomendamos usar fixed plans para essas operações de gravação em tempo real para melhorar a eficiência da atualização de dados.RPS

  • Para visualize o plano de execução de SQL, execute uma instrução EXPLAIN. Se o plano de execução retornado contiver FixedXXXNode, um fixed plan foi acionado, conforme mostrado na figura a seguir. Se o plano de execução não contiver FixedXXXNode, revise as condições de suporte descritas nas seções anteriores e verifique se sua instrução atende aos requisitos.验证fixedplan

Ajuste de desempenho

Se você ainda precisar ajustar o desempenho com um fixed plan habilitado, use os métodos a seguir.

  • Analise o plano de execução para identificar gargalos de desempenho. Execute EXPLAIN em uma instrução SQL para visualize o tempo consumido em cada etapa e localizar gargalos.

  • As versões 1.1.49 e posteriores do Hologres são otimizadas para consultas pontuais que usam um fixed plan, melhorando o throughput em mais de 30% em cenários de grande escala. Para se beneficiar dessa melhoria, atualize sua instância para a V1.1.49 ou uma versão posterior.

  • Utilize o agrupamento em lote no lado do cliente com um tamanho de lote de 512 ou um múltiplo de 512. O Holo Client lida com o agrupamento em lote automaticamente.

Perguntas frequentes

  • Sintoma: Ao tentar conectar-se ao Hologres, ocorre o seguinte erro: role/database does not exist.

    • Causa: O usuário ou banco de dados especificado não existe.

    • Solução: Verifique suas informações de conexão e certifique-se de que o nome de usuário e o nome do banco de dados estejam corretos.

      Faça login no console do Hologres. Localize a instância de destino e clique em Manage na coluna Actions. Clique em Database Management. Em seguida, verifique o nome de usuário na página Users e o nome do banco de dados na página Database Authorization.

  • Sintoma: Durante uma operação de gravação de dados, ocorre o seguinte erro: the requested table name: xxx (id: xx, version: xx) mismatches the version of the table (id: xx, version: xx) from server.

    • Causa: Os metadados da tabela mudam durante a operação de gravação de dados (por exemplo, uma coluna é adicionada), o que altera a versão da tabela.

    • Solução: Restabeleça a conexão. O fixed plan então recupera os novos metadados da tabela para concluir a operação de gravação.