All Products
Search
Document Center

Hologres:Accelerate the execution of SQL statements by using fixed plans

Last Updated:Dec 02, 2024

The fixed plan feature is exclusive for Hologres execution engines. This topic describes the conditions and parameter settings for SQL statements that can use fixed plans.

Background information

The fixed plan feature is exclusive for Hologres execution engines. Normally, SQL statements are processed by a series of Hologres components, including the optimizer, coordinator, query engine, and storage engine. You can use a fixed plan to accelerate the execution of an SQL statement by skipping the processing of the optimizer, coordinator, and specific query engines. In a fixed plan, a fixed frontend (FE) node distributes an SQL statement to a fixed query engine. This significantly improves execution performance and implements high-throughput real-time data writes and a large number of concurrent queries. For more information about the fixed plan feature, see Architecture.

In Hologres, the fixed plan feature is automatically used in the following scenarios:

  • Real-time data writes to Hologres by using Flink.

  • Real-time data writes to Hologres by using Data Integration of DataWorks.

  • Data writes to Hologres by using Holo Client.

In other data write scenarios, you can configure Grand Unified Configuration (GUC) parameters to enable the fixed plan feature for SQL statements by following the instructions in the following sections.

Note

By default, SQL statements are processed by using the fixed plan feature if the SQL statements meet the conditions specified in the preceding scenarios. Otherwise, the SQL statements are not be processed by using the fixed plan feature.

GUC parameters related to the fixed plan feature

  • GUC parameters

    The following table describes the GUC parameters related to the fixed plan feature. The valid values of all the GUC parameters are on and off. By default, all the GUC parameters are set to on in Holo Client and take effect at the session level.

    GUC parameter

    Description

    Default value

    GUC change record

    hg_experimental_enable_fixed_dispatcher

    Specifies whether to enable the fixed plan feature for the Hologres instance.

    SQL statements that are used to write data to, update data in, delete data from, or query data in a single row can be processed by using fixed plans. Such SQL statements include the INSERT, UPDATE, and DELETE statements and prefix query statements.

    on

    N/A.

    hg_experimental_enable_fixed_dispatcher_for_multi_values

    Specifies whether to allow the execution of an INSERT ON CONFLICT statement by using a fixed plan to write data to multiple rows.

    Note

    The atomicity of the write operation is not guaranteed. If no error is reported, data is written to all rows. If an error is reported, no data is written to the rows, or data is written to the specified rows. The information about the rows that fail to be written is reported to the upper-layer application. The upper-layer application tries to write these rows again.

    on

    In Hologres V1.3.35 and later, this GUC parameter specifies whether to allow the INSERT, UPDATE, and DELETE statements to be executed on multiple rows by using a fixed plan.

    hg_experimental_enable_fixed_dispatcher_autofill_series

    Specifies whether to allow the execution of a statement that involves a column of the SERIAL data type by using a fixed plan. We recommend that you enable this feature at the session level on your client.

    off

    In Hologres V1.3.25 and later, the default value of this GUC parameter is on.

    hg_experimental_enable_fixed_dispatcher_for_update

    Specifies whether to allow the execution of the UPDATE statement by using a fixed plan. We recommend that you enable this feature at the session level on your client.

    off

    In Hologres V1.3.25 and later, this parameter is no longer used. An UPDATE statement that meets conditions is automatically processed by using a fixed plan. If you want to update data in multiple rows by using the UPDATE statement, you must configure set hg_experimental_enable_fixed_dispatcher_for_multi_values =on.

    hg_experimental_enable_fixed_dispatcher_for_delete

    Specifies whether to allow the execution of the DELETE statement by using a fixed plan. We recommend that you enable this feature at the session level on your client.

    off

    In Hologres V1.3.25 and later, this parameter is no longer used. A DELETE statement that meets conditions is automatically processed by using a fixed plan. If you want to delete data from multiple rows by using the DELETE statement, you must configure set hg_experimental_enable_fixed_dispatcher_for_multi_values =on.

    hg_experimental_enable_fixed_dispatcher_for_scan

    Specifies whether to allow the execution of a prefix query statement by using a fixed plan.

    Note

    In a prefix query, only the first several primary key columns of a table are specified in the query statement. Hologres does not support the execution of a prefix query on a column-oriented table by using a fixed plan.

    off

    We recommend that you use this parameter for Hologres V1.3.35 and later.

    hg_experimental_enable_bhclient_cache_on_session

    Specifies whether to use the cached on session mode or cached on FE mode to cache data. Valid values:

    • on: uses the cached on session mode.

    • off: uses the cached on FE mode.

    Note

    The cached on session and cached on FE modes have the following differences:

    • In cached on session mode, each session is provided with a reader and a writer. This mode provides higher throughput per connection, but statements take a longer time to execute in this mode. This is because the reader and the writer take time to start when you read data from or write data to a table for the first time.

    • In cached on FE mode, all sessions on an FE node share a reader and a writer. If a session is closed, the reader and the writer are still ready to be used. This saves the startup time for the reader and the writer.

    off

    N/A.

    hg_experimental_disable_fixed_planner_conflict_pk_check

    Specifies whether to allow non-primary key columns to be specified in the INSERT INTO <table_name> VALUES (...) ON CONFLICT(<column>) syntax.

    • false: not allowed.

    • true: allowed.

      Note

      If this parameter is set to true, non-primary key columns are allowed. In actual situations, the INSERT ON CONFLICT statement is executed based on ON CONFLICT(pk).

    false

    • In Hologres V1.3 to V2.1.28, columns specified in ON CONFLICT(<column>) must be primary key columns.

    • In Hologres V2.1.29 and later, you can use the GUC parameter to specify whether to allow non-primary key columns in ON CONFLICT(<column>).

  • Use a GUC parameter

    • Check the setting of a GUC parameter

      You can execute the following SHOW statement to check the setting of a GUC parameter:

      show <GUC_name>;

      The following example is for your reference:

      -- Check whether the fixed plan feature is enabled at the instance level.
      show hg_experimental_enable_fixed_dispatcher;
    • Configure a GUC parameter

      • Configure a GUC parameter at the session level

        You can use the SET statement to configure a GUC parameter at the session level. If you configure a GUC parameter at the session level, the setting takes effect only in the current session. After the session is closed, the setting becomes invalid. We recommend that you execute the following statement before you execute the SQL statement.

        set <GUC_name> = <values>;

        The GUC_name parameter specifies the name of the GUC parameter, and the values parameter specifies the value that you want to configure for the GUC parameter.

        The following example is for your reference:

        -- Allow the execution of the INSERT ON CONFLICT statement that writes data to multiple rows by using a fixed plan.
        set hg_experimental_enable_fixed_dispatcher_for_multi_values =on;
      • Configure a GUC parameter at the database level

        You can execute the alter database xx set xxx statement to configure the GUC parameter at the database level. After you configure the GUC parameter, you must reconnect the connection to make the configuration take effect. For a new database, you must manually reconfigure the setting. Sample statement:

        alter database <db_name> set <GUC_name> = <values>;

        Replace db_name with the name of the database, GUC_name with the name of the GUC parameter, and values with the value that you want to configure for the GUC parameter.

        The following example is for your reference:

        -- Enable the fixed plan feature for a database.
        alter database <db_name> set
         hg_experimental_enable_fixed_dispatcher =on;

Requirements on data types

  • Each column cannot contain data of the MONEY type or MONEY arrays.

  • The following data types are supported for columns on which you want to perform DML operations such as INSERT, UPDATE, and DELETE or execute the SELECT statement. The columns to be queried and those specified in the WHERE clause of a SELECT statement must be of the following data types:

    • BOOLEAN (alias: BOOL)

    • SMALLINT

    • INTEGER (alias: INT or INT4)

    • BIGINT (alias: INT8)

    • FLOAT (alias: FLOAT4)

    • DOUBLE PRECISION (alias: FLOAT8)

    • CHAR(n)

    • VARCHAR(n)

    • BYTEA

    • JSON and JSONB

    • TEXT (alias: VARCHAR)

    • TIMESTAMP WITH TIME ZONE (alias: TIMESTAMPTZ)

    • DATE

    • TIMESTAMP

    • DECIMAL (alias: NUMERIC)

    • ROARINGBITMAP

    • TIME (supported in Hologres V2.2 and later)

    • TIMETZ (supported in Hologres V2.2 and later)

    • Array types

      • boolean[]

      • smallint[]

      • int4[]

      • int8[]

      • float4[]

      • float8[]

      • char(n)[]

      • varchar(n)[]

      • text[]

INSERT statement

  • Syntax

    To use fixed plans, execute the INSERT statement in the following syntax:

    -- Write data to a single row.
    insert into table(col1,col2,col3..) values(?,?,?..) on conflict xxx;
    -- Write data to multiple rows.
    insert into table(col1,col2,col3..) values(?,?,?..),(?,?,?..) on conflict xxx;
    Note
    • You can execute the INSERT statement to write data to Hologres internal tables but not foreign tables.

    • You can execute the INSERT statement to write data to Hologres partitioned tables. In Hologres V1.3 and later, you can execute the INSERT statement to write data to a parent partitioned table.

  • Execute the INSERT ON CONFLICT statement to write data to a single row

    • The following types of INSERT statements are supported:

      • An INSERT statement that does not contain the ON CONFLICT clause.

      • An INSERT statement that contains the ON CONFLICT DO NOTHING clause.

      • An INSERT statement that contains the ON CONFLICT DO UPDATE clause. All non-primary key columns must be updated. You can specify whether to update the primary key columns based on your business requirements. You must specify columns that you want to update in the col = excluded.col format. In Hologres V1.3 and later, you can update some of the non-primary key columns. However, you must also specify columns to be updated in the col = excluded.col format.

    • The following example is for your reference:

      begin;
      create table test_insert_oneline(
        pk1 int,
        pk2 int,
        col1 int,
        col2 int,
        primary key(pk1, pk2)
      );
      commit;
      
      -- Update all non-primary key columns. In this example, 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 primary key columns and non-primary key columns. In this example, 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;
      
      -- To use a fixed plan, you must update all non-primary key columns. In this example, the col2 column is not specified in the statement. A fixed plan can be used 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;
      
      -- To use a fixed plan, you must specify columns that you want to update in the col = excluded.col format in a SET clause. In this example, a fixed plan cannot be used.
      insert into test_insert_oneline values(1,2,3,4) on conflict(pk1,pk2) do update set col1 = excluded.col1, col2 = 5;
  • Execute the INSERT ON CONFLICT statement to write data to multiple rows

    • Syntax:

      set hg_experimental_enable_fixed_dispatcher_for_multi_values =on;
      insert into table(col1,col2,col3..) values(?,?,?..),(?,?,?..) on conflict xxx;
      • The GUC parameter hg_experimental_enable_fixed_dispatcher_for_multi_values must be set to on. In Hologres V1.3.35 and later, this parameter is set to on by default.

      • The atomicity of the write operation is not guaranteed. If no error is reported, data is written to all rows. If an error is reported, no data is written to the rows, or data is written to some rows.

    • The following syntax can also be used to write data to multiple rows:

      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;
      • The GUC parameter hg_experimental_enable_fixed_dispatcher_for_multi_values must be set to on.

      • Data of the ARRAY type cannot be written to the table.

      • In the UNNEST clause, the specified arrays must be explicitly converted to the array types of the corresponding columns.

      The following example is for your reference:

      begin;
      create table test_insert_multiline(
        pk1 int8,
        col1 float4,
        primary key(pk1)
      );
      commit;
      
      -- In this example, a fixed plan can be used.
      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;
      
      -- In this example, the specified array in the UNNEST clause is not explicitly converted to the array type of the corresponding column. Therefore, a fixed plan cannot be used.
      insert into test_insert_multiline select unnest(ARRAY[1,2,3]), unnest(ARRAY[1.11,2.222,3]) on conflict do nothing;
      
      -- The data type of the first column is INT8. Therefore, the array must be explicitly converted to the INT8 type. In this example, the array is explicitly converted to the INT4 type. Therefore, a fixed plan cannot be used.
      insert into test_insert_multiline select unnest(ARRAY[1,2,3]::int4[]), unnest(ARRAY[1.11,2.222,3]::float4[]) on conflict do nothing;
  • Update specific columns in a table

    Hologres allows you to update specific columns in a table based on the primary key. You can use fixed plans to update specific columns in a table if the following conditions are met:

    • The columns that you want to write data to map the columns that you want to update in both quantity and sequence.

    • The columns to be updated are specified in the col = excluded.col format.

  • Execute the UPDATE or INSERT statement with conditional clauses

    To cope with the out-of-order requirements of the input data in the rows that share the same primary key and to support HBase CheckAndPut, Hologres allows you to use fixed plans to execute the INSERT or UPDATE statement with conditional clauses.

    • Fixed plans can be used if you write data to a single row. If you want to write data to multiple rows, you must add the set hg_experimental_enable_fixed_dispatcher_for_multi_values=on; configuration.

    • If a WHERE clause contains only a single non-primary key field and some of the following operators are used: =, <>, >, >=, <, <=, IS NULL, and IS NOT NULL, the coalesce function can be called to process this field.

    The following example is for your reference:

    begin;
    create table test_check_and_insert(
      pk int,
      col int,
      scn int,
      primary key(pk)
    );
    commit;
    
    -- In this example, a fixed plan can be used.
    -- Compare the existing values in a column with constants.
    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 values in a column with the written values.
    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 is null, the coalesce function can be used.
    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;
    
    -- In this example, a fixed plan can be used.
    set hg_experimental_enable_fixed_dispatcher_for_multi_values =on;
    -- Compare the existing values in a column with constants.
    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 clause is 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;
  • Write data to a table that contains a column with the DEFAULT constraint

    You can use fixed plans to write data to a table that contains a column with the DEFAULT constraint.

    • Fixed plans can be used if a single row of data is inserted. If you want to write data to multiple rows, the version of your Hologres instance must be V1.1.36 or later. Otherwise, you must update your instance. The GUC parameter hg_experimental_enable_fixed_dispatcher_for_multi_values must be set to on.

    • In Hologres V1.3 and later, you can use fixed plans to execute the INSERT ON CONFLICT statement on a table that contains a column with the DEFAULT constraint. In a version earlier than Hologres V1.3, you cannot use fixed plans to execute the INSERT ON CONFLICT statement on a table that contains a column with the DEFAULT constraint.

    The following example is for your reference:

    begin;
    create table test_insert_default(
      pk1 int,
      col1 int default 99,
      primary key(pk1)
    );
    commit;
    
    -- In this example, a fixed plan can be used.
    insert into test_insert_default(pk1) values(1);
    
    -- You must use an instance of 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);
  • Write data to a table that contains a column of the SERIAL data type

    You can use fixed plans to write data to a single row or multiple rows of a table that contains a column of the SERIAL data type.

    • The GUC parameter hg_experimental_enable_fixed_dispatcher_autofill_series must be set to on. In Hologres V1.3.25 and later, the default value of this parameter is on.

    • The GUC parameter hg_experimental_enable_fixed_dispatcher_for_multi_values must be set to on if you want to write data to multiple rows.

    The following example is for your reference:

    begin;
    create table test_insert_serial(
      pk1 int,
      col1 serial,
      primary key(pk1)
    );
    commit;
    
    -- In this example, a fixed plan can be used.
    set hg_experimental_enable_fixed_dispatcher_autofill_series =on;
    insert into test_insert_serial (pk1) values(1);
    
    -- In this example, a fixed plan can be used.
    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 statement

  • Syntax

    To use fixed plans, execute the UPDATE statement in the following syntax:

    set hg_experimental_enable_fixed_dispatcher_for_update =on;
    update table set col1 = ?, col2 = ? where pk1 = ? and pk2 = ?;
  • Usage notes

    When you execute the UPDATE statement by using fixed plans, take note of the following items:

    • You can update data in an internal table instead of a foreign table. You can update data in child partitioned tables instead of a parent partitioned table. The specified table must have a primary key.

    • The GUC parameter hg_experimental_enable_fixed_dispatcher_for_update must be set to on. In Hologres V1.3.25 and later, this parameter is no longer used. An UPDATE statement that meets conditions is automatically processed by using a fixed plan. If you want to update data in multiple rows by using the UPDATE statement, you must set the GUC parameter hg_experimental_enable_fixed_dispatcher_for_multi_values to on.

    • You cannot specify primary key columns in the SET clause.

    • You must specify all primary key columns in the WHERE clause.

    • You can use the pk in (?,?,?) or pk = ANY() format to update multiple rows at a time. Example: pk1 in (1,2) and pk2 = any('{3,4}') and pk3 = 5. In this case, the four rows (1,3,5), (1,4,5), (2,3,5), and (2,4,5) are updated.

    • You can specify only one condition in the WHERE clause for a column. Duplicate conditions are considered one condition.

    The following example is for your reference:

    begin;
    create table test_update(
      pk1 int,
      pk2 int,
      col1 int,
      col2 int,
      primary key(pk1, pk2)
    );
    commit;
    
    -- In this example, a fixed plan can be used.
    set hg_experimental_enable_fixed_dispatcher_for_update =on;
    
    update test_update set col1 = 1, col2 = 2 where pk1 = 3 and pk2 = 4;
    
    -- In this example, a fixed plan can be used.
    set hg_experimental_enable_fixed_dispatcher_for_update =on;
    update test_update set col1 = 1 where pk1 = 3 and pk2 = 4;
    
    -- In this example, a fixed plan can be used.
    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}');
    
    -- In this example, multiple conditions are specified for the pk1 column in the WHERE clause. Therefore, a fixed plan cannot be used.
    update test_update set col1 = 1, col2 = 2 where pk1 = 3 and pk1 = 4;
    
    -- In this example, multiple conditions are specified for the pk1 column in the WHERE clause. Therefore, a fixed plan cannot be used.
    update test_update set col1 = 1, col2 = 2 where pk1 in (1,2) and pk1 = 1;
    
    -- In this example, multiple duplicate conditions are specified for the pk1 column in the WHERE clause. Therefore, a fixed plan can be used.
    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 statement

  • Syntax

    To use fixed plans, execute the DELETE statement in the following syntax:

    set hg_experimental_enable_fixed_dispatcher_for_delete =on;
    delete from table where pk1 = ? and pk2 = ? and pk3 = ?;
  • Usage notes

    When you execute the DELETE statement by using fixed plans, take note of the following items:

    • You can delete data in an internal table instead of a foreign table. You can delete data in child partitioned tables instead of a parent partitioned table. The specified table must have a primary key.

    • The GUC parameter hg_experimental_enable_fixed_dispatcher_for_delete must be set to on. In Hologres V1.3.25 and later, this parameter is no longer used. A DELETE statement that meets the conditions is automatically processed by using a fixed plan. If you want to delete data from multiple rows by using the DELETE statement, you must set the GUC parameter hg_experimental_enable_fixed_dispatcher_for_multi_values to on.

    • You must specify all primary key columns in the WHERE clause. In Hologres V1.3 and later, the last field in the WHERE clause can be a non-primary key field. The non-primary key field support the following operators: =, <>, >, >=, <, <=, IS NULL, and IS NOT NULL. The coalesce function can be called to process this field.

    • You can use the pk in (?,?,?) or pk = ANY() format to delete multiple rows at a time. Example: pk1 in (1,2) and pk2 = any('{3,4}') and pk3 = 5. In this case, the four rows (1,3,5), (1,4,5), (2,3,5), and (2,4,5) are deleted.

    • You can specify only one condition in the WHERE clause for a column. Duplicate conditions are considered one condition.

    The following example is for your reference:

    begin;
    create table test_delete(
      pk1 int,
      pk2 int,
      col1 int,
      col2 int,
      primary key(pk1, pk2)
    );
    commit;
    
    -- In this example, a fixed plan can be used. View the description of the UPDATE statement for more examples.
    set hg_experimental_enable_fixed_dispatcher_for_delete =on;
    delete from test_delete where pk1 = 1 and pk2 = 2;

SELECT statement

  • Syntax

    To use fixed plans, execute the SELECT statement in the following syntax:

    select col1,col2,col3,... from table where pk1 = ? and pk2 = ? and pk3 = ?;
    • You can query data in an internal table instead of a foreign table.

    • You can query data in child partitioned tables instead of a parent partitioned table.

    • The specified table must have a primary key.

  • Perform point queries of key-value pairs

    When you perform point queries by using fixed plans, take note of the following items:

    • You must specify all primary key columns in the WHERE clause.

    • You can use the pk in (?,?,?) or pk = ANY() format to query multiple rows at a time. Example: pk1 in (1,2) and pk2 = any('{3,4}') and pk3 = 5. In this case, the four rows (1,3,5), (1,4,5), (2,3,5), and (2,4,5) are queried.

    • You can specify only one condition in the WHERE clause for a column. Duplicate conditions are considered one condition.

    • If you specify a limit for the returned result, the value of the limit must be greater than 0.

    The following example is for your reference:

    begin;
    create table test_select(
      pk1 int,
      pk2 int,
      col1 int,
      col2 int,
      primary key(pk1, pk2)
    );
    commit;
    
    -- In this example, a fixed plan can be used.
    select * from test_select where pk1 = 1 and pk2 = 2;
  • Perform prefix queries

    • Syntax

      If the primary key of a table contains multiple columns, you can specify only the first several primary key columns to perform prefix queries. The prefix queries are performed based on the leftmost prefix matching principle. Syntax:

      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 pk 2 < ?;-- In Hologres V1.1.48 and later, the last primary key column can be used to specify the query range.
      select col1,col2,col3,... from table where pk1 = ? and pk2 between ? and ?;-- In Hologres V1.1.48 and later, the last primary key column can be used to specify the query range.
    • Usage notes

      To perform prefix queries by using fixed plans, take note of the following items:

      • The GUC parameter hg_experimental_enable_fixed_dispatcher_for_scan must be set to on. The version of your Hologres instance must be V1.1.24 or later. We recommend that you use Hologres V1.3.35 or later.

      • Distribution keys must be specified for tables. You must specify all distribution key columns in the WHERE clause.

      • You must specify only prefixes of all primary key columns in the WHERE clause. In Hologres V1.1.48 and later, the last primary key column can be used to specify the query range.

        Note

        Example of prefix columns: If (pk1,pk2,pk3) is specified for the primary key, (pk1) or (pk1,pk2) is used as the prefix.

      • Prefix queries cannot be performed on column-oriented tables.

      • You can specify only one condition in the WHERE clause for a column. Duplicate conditions are considered one condition.

      • If you specify a limit for the returned result, the value of the limit must be greater than 0.

      Note

      Prefix queries return all result rows at a time. If the size of the rows exceeds the limit specified by the hg_experimental_fixed_scan_bytesize_limit parameter, the error message scan result size larger than fixed scan size limit is reported. You can set the hg_experimental_fixed_scan_bytesize_limit parameter to an appropriate value. The default value is 1048576, which indicates 1 MB.

      If (pk1,pk2,pk3,pk4) is configured for the primary key, pk1,pk3 is configured for the distribution key.

      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;
      
      
      -- In this example, not all distribution key columns are specified in the WHERE clause. Therefore, a fixed plan cannot be used.
      select * from test_select_prefix where pk1 = ? and pk2 = ?;
      
      -- In this example, the prefix of the primary key columns is not used. Therefore, a fixed plan cannot be used.
      select * from test_select_prefix where pk1 = ? and pk3 =?;
      
      -- In this example, 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 = ?;
      
      

      You can use the pk in (?,?,?) or pk = ANY() format to query multiple rows at a time. Syntax:

      pk1 in (1,2) and pk2 = 3 <=> Query the (1,3) and (2,3) rows.
      pk2 =any('{3,4}') and pk1 in (1,2) <=> Query the (1,3), (1,4), (2,3), and (2,4) rows.
    • The following example is for your reference:

      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);
      
      -- In this example, a fixed plan can be used.
      set hg_experimental_enable_fixed_dispatcher_for_scan = on;
      select * from test_scan where pk1 = 1 and pk2 = 2;
      
      -- In this example, a fixed plan can be used.
      set hg_experimental_enable_fixed_dispatcher_for_scan = on;
      select * from test_scan where pk1 = 1 and pk2 in (2,3);
      
      -- In this example, a fixed plan can be used.
      set hg_experimental_enable_fixed_dispatcher_for_scan = on;
      select * from test_scan where pk1 = ANY('{3,4}') and pk2 in (2,3);
      
      -- In this example, a fixed plan can be used. The last primary key column can be used to specify the query range, which is supported by Hologres V1.1.48 and 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;
      
      -- In this example, a fixed plan can be used. The last primary key column can be used to specify the query range, which is supported by Hologres V1.1.48 and 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;
      
      -- In this example, not all distribution key columns are specified in the WHERE clause. Therefore, a fixed plan cannot be used.
      select * from test_scan where pk1 = 1;
      
      -- In this example, the prefix of the primary key columns is not used. Therefore, a fixed plan cannot be used.
      select * from test_scan where pk2 = 2;

COPY statement

In Hologres 1.3.17 and later, you can use fixed plans to execute the COPY statement. The following table describes the differences between fixed plans and other plans.

Item

Fixed plan

Other plan

Lock type

Row lock

Table lock

Data visibility

Data can be queried after it is written.

Data can be queried after a COPY statement is executed.

Performance

Good

Excellent

Supported data type

TEXT and BINARY

TEXT

Supported primary key conflict policies

The following policies are supported:

  • NONE: returns an error when a primary key conflict occurs.

  • IGNORE: skips the data where a primary key conflict occurs.

  • UPDATE: updates the data where a primary key conflict occurs.

NONE: returns an error when a conflict occurs.

The following table describes the parameters that are added to the COPY statement.

Parameter

Description

stream_mode

Specifies whether to use a fixed plan. Valid values:

  • true: A fixed plan is used.

  • false: A fixed plan is not used.

on_conflict

The conflict policy. Valid values:

  • NONE: returns an error when a primary key conflict occurs.

  • IGNORE: skips the data where a primary key conflict occurs.

  • UPDATE: updates the data where a primary key conflict occurs.

The following example is for your reference:

COPY table_name(column0,column1,column2) FROM STDIN
WITH (
  format binary,
  stream_mode true,
  on_conflict update);

If not all columns are copied, the specific COPY statement varies.

  • If part of columns are copied, the table is partially updated. Statement:

    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 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;
  • If only part of columns are copied and default values are configured for the columns that are not copied, the following statement is used:

    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 is equivalent to the following INSERT INTO statement.
    -- For a row of data, if the id column of the row contains no data, the age column of the row is assigned the default value.
    -- For a row of data, if data is available in the id column, the age column of the row is not updated.
    INSERT INTO t0(id, name, age) VALUES(?, ?, default)
    ON CONFLICT(id) DO UPDATE SET
    id = excluded.id, name = excluded.name;

Verify that a fixed plan is used

  • In the Hologres console, update statements that are executed by using fixed plans are displayed in the Real-time Import (RPS) section of the Monitoring Information page as INSERT, UPDATE, and DELETE operations performed by using SDKs. We recommend that you execute the INSERT, UPDATE, and DELETE statements by using fixed plans to improve data update efficiency.RPS

  • You can execute the EXPLAIN statement to view the SQL execution plan and verify that a fixed plan is used. If the returned execution plan contains FixedXXXNode, a fixed plan is triggered to process the SQL statement, as shown in the following figure. If FixedXXXNode is not returned in the execution plan, check whether the requirements described in the preceding sections are met.验证fixedplan

Optimize performance

In specific scenarios in which fixed plans are used, you can use one of the following methods to optimize performance:

  • The performance of point queries performed by using fixed plans is optimized in Hologres V1.1.49 and later. In point queries that involve a large amount of data, the throughput is improved by more than 30%. Update the instance to V1.1.49 or later based on your business requirements.

  • Set the number of SQL statements that you want to execute at a time to a multiple of 512. Practices have proven that when the number of SQL statements that you want to execute at a time is set to a multiple of 512, the performance is optimal. In Holo Client, the number of SQL statements is automatically set to a multiple of 512.

FAQ

  • Question 1: What do I do if the error message role/database does not exist. is reported for a connection?

    • Cause: The user account or database does not exist.

    • Solution: Check the connection information and make sure that the username or database name is valid.

      You can log on to the Hologres console, find the desired instance, and click Manage in the Actions column. Click Account Management in the left-side navigation pane of the Instance Details page. Then, you can obtain the username on the User Management page and the database name on the Database Authorization page.

  • Question 2: What do I do if the error message the requested table name: xxx (id: xx, version: xx) mismatches the version of the table (id: xx, version: xx) from server is reported during data writes?

    • Cause: The table metadata changes due to operations such as column addition during data writes. As a result, the table version changes.

    • Solution: Re-establish the connection. In fixed plans, the new table metadata is obtained and the data is written.