日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

Fixed Plan加速SQL執行

Fixed Plan是Hologres特有的執行引擎優化方式,本文將為您介紹可以被Fixed Plan選中的SQL需要符合的條件和參數配置。

背景信息

Fixed Plan是Hologres特有的執行引擎優化方式,傳統的SQL執行要經過優化器、協調器、查詢引擎、存儲引擎等多個組件,而Fixed Plan選擇了短路徑(Short-Cut)優化執行SQL,繞過了優化器、協調器、部分查詢引擎的開銷。通過Fixed FrontEnd直接對接Fixed Query Engine,實現SQL執行效率的成倍提升,是支持高吞吐實時寫入,高并發查詢的關鍵優化方法。關于Fixed Plan的介紹請參見產品架構

在Hologres中,默認走Fixed Plan的場景如下:

  • Flink實時寫入數據至Hologres。

  • DataWorks數據集成實時寫入數據至Hologres。

  • Holo Client寫入Hologres。

其余寫入場景可根據SQL進行一定的配置讓其走Fixed Plan,詳情請參見下文。

說明

以上場景會默認保證符合條件的SQL走Fixed Plan,但是以上場景的SQL不一定都符合條件即不一定都能走Fixed Plan。

相關GUC參數

  • GUC列表

    以下為Fixed Plan需要用到的參數配置,所有參數取值為on或者off。所有參數已經在Holo Client中默認打開,Session級別生效。

    GUC名稱

    適用場景

    默認值

    GUC變更記錄

    hg_experimental_enable_fixed_dispatcher

    查看實例的Fixed Plan是否打開。

    支持Insert、Update、Delete、PrefixScan場景單行記錄的Fixed Plan寫入、更新、刪除、查詢。

    on

    不涉及。

    hg_experimental_enable_fixed_dispatcher_for_multi_values

    控制Insert多行記錄的Fixed Plan寫入。

    說明

    不保證原子性,即一次性寫入多條的時候,如果沒報錯就是全部正常寫入了,如果報錯了只會報一條的錯誤,有可能全部沒寫入也有可能部分寫入了部分沒寫入,沒有寫入的部分會將錯誤反饋給上層應用端,由應用端進行重試。

    on

    Hologres從V1.3.35版本開始,通過該GUC支持Insert、Update、Delete多行記錄的Fixed Plan寫入、更新、刪除。

    hg_experimental_enable_fixed_dispatcher_autofill_series

    支持含有Serial類型列的Fixed Plan寫入。建議客戶端session級別打開。

    off

    Hologres從V1.3.25版本開始,該GUC參數的默認值為on

    hg_experimental_enable_fixed_dispatcher_for_update

    支持更新(UPDATE)場景的Fixed Plan更新。建議客戶端session級別打開。

    off

    Hologres從V1.3.25版本開始,hg_experimental_enable_fixed_dispatcher_for_update廢棄使用,即符合條件的UPDATE語句會默認使用Fixed Plan,但UPDATE多行記錄需要配置set hg_experimental_enable_fixed_dispatcher_for_multi_values =on

    hg_experimental_enable_fixed_dispatcher_for_delete

    支持刪除(DELETE)場景的Fixed Plan刪除。建議客戶端session級別打開。

    off

    Hologres從V1.3.25版本開始,hg_experimental_enable_fixed_dispatcher_for_delete廢棄使用即符合條件的DELETE語句會默認走Fixed Plan,但DELETE多行記錄需要配置set hg_experimental_enable_fixed_dispatcher_for_multi_values =on

    hg_experimental_enable_fixed_dispatcher_for_scan

    支持PrefixScan場景的Fixed Plan查詢。

    說明

    PrefixScan是指多列主鍵,查詢條件只給前面幾列主鍵。目前不支持列存表PrefixScan場景的Fixed Plan查詢。

    off

    推薦從1.3.35版本開始使用。

    hg_experimental_enable_bhclient_cache_on_session

    支持更改緩存模式,存在以下兩種情況。

    • on:使用cached on session模式。

    • off:使用cached on fe模式。

    說明

    cached on sessioncached on fe的區別如下。

    • cached on session是每個連接擁有自己的Writer、Reader,單連接的吞吐更好,但啟動會更慢(每個表第一次進行讀或寫時需要有啟動時間)。

    • cached on fe是FE(Frontend)節點上所有連接共享Writer、Reader,連接斷開后Writer、Reader不會關閉,所以總體上沒有啟動時間。

    off

    不涉及。

    hg_experimental_disable_fixed_planner_conflict_pk_check

    控制INSERT INTO <table_name> VALUES (...) ON CONFLICT(<column>)語法中的column是否支持非主鍵字段。

    • false:不支持。

    • true:支持。

      說明

      該GUC參數設置為true,column支持填寫非主鍵字段,但INSERT ON CONFLICT語句實際執行時,還是按照主鍵是否重復(ON CONFLICT(pk))來處理數據。

    false

    • Hologres從V1.3至V2.1.28版本,ON CONFLICT(<column>)中的字段必須為主鍵字段。

    • Hologres從V2.1.29版本開始,通過該GUC參數控制ON CONFLICT(<column>)中的字段是否支持非主鍵字段。

  • GUC使用

    • 查看GUC是否開啟

      通過show命令查看GUC是否開啟,命令語句如下。

      SHOW <GUC_name>;

      使用示例如下。

      -- 查看實例級別是否開啟Fixed Plan
      SHOW hg_experimental_enable_fixed_dispatcher;
    • 開啟GUC

      • session級別開啟GUC

        通過set命令可以在session級別設置GUC參數。session級別的參數只在當前session生效,當連接斷開之后,將會失效,建議加在SQL前一起執行,語法示例如下。

        SET <GUC_name> = <values>;

        GUC_name為GUC參數的名稱;values為GUC參數的值。

        使用示例如下。

        -- insert on conflict多行記錄支持Fixed Plan寫入
        SET hg_experimental_enable_fixed_dispatcher_for_multi_values =on;
      • 數據庫級別開啟GUC

        通過alter database xx set xxx命令來設置數據庫級別的GUC參數,執行完成后在整個數據庫生效,設置完成后當前連接需要重新斷開連接才能生效。新建數據庫不會生效,需要重新手動設置,語法示例如下。

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

        db_name為數據庫名稱,GUC_name為GUC參數的名稱,values為GUC參數的值。

        使用示例如下。

        --DB級別開啟fixed plan
        ALTER database <db_name> SET hg_experimental_enable_fixed_dispatcher =on;

數據類型要求

  • 表的每一列都不能是MONEY或MONEY ARRAY類型。

  • 進行DML(INSERT、UPDATE、DELETE)操作的列和進行SELECT(select的target列和where里的列都要滿足)操作的列支持的類型如下。

    • BOOLEAN(別名BOOL)

    • SMALLINT

    • INTEGER(別名INT或INT4)

    • BIGINT(別名INT8)

    • FLOAT(別名FLOAT4)

    • DOUBLE PRECISION(別名FLOAT8)

    • CHAR(n)

    • VARCHAR(n)

    • BYTEA

    • JSON和JSONB

    • TEXT(別名VARCHAR)

    • TIMESTAMP WITH TIME ZONE(別名TIMESTAMPTZ)

    • DATE

    • TIMESTAMP

    • DECIMAL(別名NUMERIC)

    • ROARINGBITMAP

    • TIME(Hologres V2.2版本開始支持)

    • TIMETZ(Hologres V2.2版本開始支持)

    • 數組類型

      • boolean[]

      • smallint[]

      • int4[]

      • int8[]

      • float4[]

      • float8[]

      • char(n)[]

      • varchar(n)[]

      • text[]

INSERT場景

  • INSERT表達式

    Fixed Plan支持以下INSERT表達式。

    -- 寫入單行
    INSERT INTO TABLE(col1,col2,col3..) VALUES(?,?,?..) ON conflict xxx;
    -- 寫入多行
    INSERT INTO TABLE(col1,col2,col3..) VALUES(?,?,?..),(?,?,?..) ON conflict xxx;
    說明
    • 支持使用INSERT命令寫入內部表,不支持外部表。

    • 支持使用INSERT命令寫入分區表,Hologres V1.3及以上版本支持寫入分區父表。

  • Insert on conflict單行

    • 支持場景如下。

      • 支持沒有on conflict的表達式。

      • 支持含有on conflict do nothing的表達式。

      • 支持on conflict do update,必須更新所有insert的非PK(Primary Key,主鍵,以下簡稱PK)列,PK是否更新都可以,并且只能是col = excluded.col方式更新。Hologres V1.3及以上版本支持更新部分非PK列,但是仍僅支持col = excluded.col方式更新

    • 使用示例如下。

      BEGIN;
      CREATE TABLE test_insert_oneline (
          pk1 int,
          pk2 int,
          col1 int,
          col2 int,
          PRIMARY KEY (pk1, pk2)
      );
      COMMIT;
      
      --update所有非PK列,可以Fixed Plan
      INSERT INTO test_insert_oneline
          VALUES (1, 2, 3, 4)
      ON CONFLICT (pk1, pk2)
          DO UPDATE SET
              col1 = excluded.col1, col2 = excluded.col2;
      
      --update所有列(包含PK和非PK),可以Fixed Plan
      INSERT INTO test_insert_oneline
          VALUES (1, 2, 3, 4)
      ON CONFLICT (pk1, pk2)
          DO UPDATE SET
              col1 = excluded.col1, col2 = excluded.col2, pk1 = excluded.pk1, pk2 = excluded.pk2;
      
      --必須update所有非pk的要insert的列,此例子不包含col2,僅Hologres V1.3僅以上版本支持Fixed Plan
      INSERT INTO test_insert_oneline
          VALUES (1, 2, 3, 4)
      ON CONFLICT (pk1, pk2)
          DO UPDATE SET
              col1 = excluded.col1;
      
      --必須是set col = excluded.col方式更新,因此不能Fixed Plan
      INSERT INTO test_insert_oneline
          VALUES (1, 2, 3, 4)
      ON CONFLICT (pk1, pk2)
          DO UPDATE SET
              col1 = excluded.col1, col2 = 5;
  • Insert on conflict多行

    • insert on conflict多行時,表達式如下。

      SET hg_experimental_enable_fixed_dispatcher_for_multi_values = ON;
      
      INSERT INTO TABLE (col1, col2, col3..)
          VALUES (?, ?, ?..), (?, ?, ?..)
      ON CONFLICT xxx;
      • 需要配置GUC參數:hg_experimental_enable_fixed_dispatcher_for_multi_values=on;。Hologres從1.3.35開始,該參數默認為on

      • 不保證原子性,即一次性寫入多條的時候,如果沒報錯就是全部正常寫入了,如果報錯了有可能全部沒寫入也有可能部分寫入了部分沒寫入。

    • 寫入多行另一種寫法表達式如下。

      SET hg_experimental_enable_fixed_dispatcher_for_multi_values = ON;
      
      INSERT INTO TABLE selectunnest (ARRAY[TRUE, FALSE, TRUE]::bool[]), unnest(ARRAY[1, 2, 3]::int4[]), unnest(ARRAY[1.11, 2.222, 3]::float4[])
      ON CONFLICT xxx;
      
      • 需要配置GUC參數:hg_experimental_enable_fixed_dispatcher_for_multi_values=on;

      • 寫入的列不能是數組類型。

      • unnest里ARRAY必須顯式轉換為對應列類型的數組類型。

      使用示例如下。

      BEGIN;
      CREATE TABLE test_insert_multiline (
          pk1 int8,
          col1 float4,
          PRIMARY KEY (pk1)
      );
      COMMIT;
      
      --支持Fixed Plan
      SET hg_experimental_enable_fixed_dispatcher_for_multi_values = ON;
      
      INSERT INTO test_insert_multiline
      SELECT
          unnest(ARRAY[1, 2, 3]::int8[]),
          unnest(ARRAY[1.11, 2.222, 3]::float4[])
      ON CONFLICT
          DO NOTHING;
      
      --unnest里ARRAY沒有顯式cast,不支持Fixed Plan
      INSERT INTO test_insert_multiline
      SELECT
          unnest(ARRAY[1, 2, 3]),
          unnest(ARRAY[1.11, 2.222, 3])
      ON CONFLICT
          DO NOTHING;
      
      --第一列是int8,所以應該cast為int8[],這里例子是int4[],因此不支持Fixed Plan
      INSERT INTO test_insert_multiline
      SELECT
          unnest(ARRAY[1, 2, 3]::int4[]),
          unnest(ARRAY[1.11, 2.222, 3]::float4[])
      ON CONFLICT
          DO NOTHING;
  • 局部更新場景

    Hologres支持通過主鍵,對表的部分列更新,Fixed Plan同樣支持局部更新場景,需要滿足如下條件。

    • Insert的列需要與Update的列一一對應,包括數量和順序。

    • 只能是col = excluded.col方式更新。

  • 帶有條件判斷的Upsert

    為了應對上游數據同PK行的亂序需求,支持類HBase CheckAndPut接口,Hologres支持帶有條件判斷的InsertUpdate語句走Fixed Plan,條件如下。

    • 插入單條數據時支持;插入多條數據時,需要設置GUC參數:set hg_experimental_enable_fixed_dispatcher_for_multi_values=on;

    • where條件僅支持單個非PK字段且比較符需在=、<>、>、>=、<、<=、IS NULL、IS NOT NULL范圍內 ,可對該非PK字段使用coalesce函數。

    使用示例如下。

    BEGIN;
    CREATE TABLE test_check_and_insert (
        pk int,
        col int,
        scn int,
        PRIMARY KEY (pk)
    );
    COMMIT;
    
    --支持Fixed Plan
    --列已有值和常量比較
    INSERT INTO test_check_and_insert AS old
        VALUES (1, 1, 1)
    ON CONFLICT (pk)
        DO UPDATE SET
            col = excluded.col, scn = excluded.scn
        WHERE
            old.scn > 0;
    
    --列已有值和寫入值比較
    INSERT INTO test_check_and_insert AS old
        VALUES (1, 1, 1)
    ON CONFLICT (pk)
        DO UPDATE SET
            col = excluded.col, scn = excluded.scn
        WHERE
            old.scn > excluded.scn;
    
    --若已有值可能為null,可用coalesce
    INSERT INTO test_check_and_insert AS old
        VALUES (1, 1, 1)
    ON CONFLICT (pk)
        DO UPDATE SET
            col = excluded.col, scn = excluded.scn
        WHERE
            coalesce(old.scn, 3) > 2;
    
    INSERT INTO test_check_and_insert AS old
        VALUES (1, 1, 1)
    ON CONFLICT (pk)
        DO UPDATE SET
            col = excluded.col, scn = excluded.scn
        WHERE
            coalesce(old.scn, 3) > excluded.scn;
    
    --支持Fixed Plan
    SET hg_experimental_enable_fixed_dispatcher_for_multi_values = ON;
    
    --列已有值和常量比較
    INSERT INTO test_check_and_insert AS old
        VALUES (1, 1, 1), (2, 3, 4)
    ON CONFLICT (pk)
        DO UPDATE SET
            col = excluded.col, scn = excluded.scn
        WHERE
            old.scn > 3;
    
    --也支持unnest寫法
    INSERT INTO test_check_and_insert AS old
    SELECT
        unnest(ARRAY[5, 6, 7]::int[]),
        unnest(ARRAY[1, 1, 1]::int[]),
        unnest(ARRAY[1, 1, 1]::int[])
    ON CONFLICT (pk)
        DO UPDATE SET
            col = excluded.col,
            scn = excluded.scn
        WHERE
            old.scn > 3;
    
  • Default列

    表中含有Default列時,可以進行Fixed Plan的條件如下。

    • 插入單條數據時支持;插入多條數據時,需要Hologres實例在V1.1.36及以上版本,若低于此版本請升級實例。同時需要設置GUC參數:set hg_experimental_enable_fixed_dispatcher_for_multi_values=on;

    • Hologres V1.3及以上版本支持有Default列的表insert on conflict表達式的Fixed Plan。之前版本實例有Default列的表,不支持insert on conflict表達式的Fixed Plan。

    使用示例如下。

    BEGIN;
    CREATE TABLE test_insert_default (
        pk1 int,
        col1 int DEFAULT 99,
        PRIMARY KEY (pk1)
    );
    COMMIT;
    
    --支持Fixed Plan
    INSERT INTO test_insert_default (pk1)
        VALUES (1);
    
    --需要V1.1.36及以上版本支持
    SET hg_experimental_enable_fixed_dispatcher_for_multi_values = ON;
    
    INSERT INTO test_insert_default (pk1)
        VALUES (1), (2), (3);
  • Serial列

    表帶有自增序列Serial時,支持單條或者多條寫入進行Fixed Plan的條件如下。

    • 需要配置GUC參數:set hg_experimental_enable_fixed_dispatcher_autofill_series=on;,從Hologres V1.3.25版本開始,該GUC參數默認為on

    • 插入多條數據時,還需配置GUC參數:set hg_experimental_enable_fixed_dispatcher_for_multi_values=on;

    使用示例如下。

    BEGIN;
    CREATE TABLE test_insert_serial (
        pk1 int,
        col1 serial,
        PRIMARY KEY (pk1)
    );
    COMMIT;
    
    --支持Fixed Plan
    SET hg_experimental_enable_fixed_dispatcher_autofill_series = ON;
    
    INSERT INTO test_insert_serial (pk1)
        VALUES (1);
    
    --支持Fixed Plan
    SET hg_experimental_enable_fixed_dispatcher_autofill_series = ON;
    
    SET hg_experimental_enable_fixed_dispatcher_for_multi_values = ON;
    
    INSERT INTO test_insert_serial (pk1)
        VALUES (1), (2), (3);
    

UPDATE場景

  • Update表達式

    Update時能進行Fixed Plan的表達式如下。

    SET hg_experimental_enable_fixed_dispatcher_for_update = ON;
    
    UPDATE TABLE SET col1 = ?,col2 = ? WHERE pk1 = ? AND pk2 = ?;
  • Update場景使用

    Update場景支持進行Fixed Plan的條件如下。

    • 支持更新內部表,不支持更新外部表;支持更新分區子表,不支持更新分區父表;表必須有主鍵(PK)。

    • 需要配置GUC參數:hg_experimental_enable_fixed_dispatcher_for_update=on; 。Hologres從 V1.3.25版本開始,該參數廢棄使用,符合條件的Update則會默認走Fixed Plan,但如果是Update更新多行時,需要配置GUC參數:set hg_experimental_enable_fixed_dispatcher_for_multi_values =on

    • set的列不能是主鍵(PK)。

    • where條件里有且只能有全部的PK。

    • 可以使用pk in (?,?,?) 或 pk = ANY() 一次修改多條。示例:pk1 in (1,2) and pk2 = any('{3,4}') and pk3 = 5,改(1,3,5),(1,4,5),(2,3,5),(2,4,5)四條。

    • where條件里同一列只能有一個條件(一模一樣的視為一個條件)。

    使用示例如下。

    BEGIN;
    CREATE TABLE test_update (
        pk1 int,
        pk2 int,
        col1 int,
        col2 int,
        PRIMARY KEY (pk1, pk2)
    );
    COMMIT;
    
    --支持Fixed Plan
    SET hg_experimental_enable_fixed_dispatcher_for_update = ON;
    
    UPDATE
        test_update
    SET
        col1 = 1,
        col2 = 2
    WHERE
        pk1 = 3
        AND pk2 = 4;
    
    --支持Fixed Plan
    SET hg_experimental_enable_fixed_dispatcher_for_update = ON;
    
    UPDATE
        test_update
    SET
        col1 = 1
    WHERE
        pk1 = 3
        AND pk2 = 4;
    
    --支持Fixed Plan
    SET hg_experimental_enable_fixed_dispatcher_for_update = ON;
    
    UPDATE
        test_update
    SET
        col1 = 1,
        col2 = 2
    WHERE
        pk1 IN (1, 2)
        AND pk2 = ANY ('{3,4}');
    
    --pk1多個過濾條件,不支持Fixed Plan
    UPDATE
        test_update
    SET
        col1 = 1,
        col2 = 2
    WHERE
        pk1 = 3
        AND pk1 = 4;
    
    --pk1多個過濾條件,不支持Fixed Plan
    UPDATE
        test_update
    SET
        col1 = 1,
        col2 = 2
    WHERE
        pk1 IN (1, 2)
        AND pk1 = 1;
    
    --pk1多個過濾條件,但過濾條件相同,支持Fixed Plan
    SET hg_experimental_enable_fixed_dispatcher_for_update = ON;
    
    UPDATE
        test_update
    SET
        col1 = 1,
        col2 = 2
    WHERE
        pk1 IN (1, 2)
        AND pk1 IN (1, 2)
        AND pk2 = 4;
    

DELETE場景

  • Delete表達式

    Delete時能進行Fixed Plan的表達式如下。

    SET hg_experimental_enable_fixed_dispatcher_for_delete = ON;
    
    DELETE FROM TABLE
    WHERE pk1 = ?
        AND pk2 = ?
        AND pk3 = ?;
  • Delete場景使用

    Delete場景支持進行Fixed Plan的條件如下。

    • 支持Delete內部表,不支持Delete外部表;支持Delete分區子表,不支持Delete分區父表;表必須有主鍵(PK)。

    • 需要配置GUC參數:hg_experimental_enable_fixed_dispatcher_for_delete=on; 。Hologres從 V1.3.25版本開始,該參數廢棄使用,符合條件的Delete則會默認走Fixed Plan,但如果是Delete多行時,需要配置GUC參數:set hg_experimental_enable_fixed_dispatcher_for_multi_values =on

    • where條件里有且只能有全部的PK,從Hologres V1.3版本開始,支持where過濾條件的最后一個字段為非PK字段,該非PK字段支持=、<>、>、>=、<、<=、IS NULL、IS NOT NULL 比較符以及使用coalesce函數。

    • 可以使用pk in (?,?,?) 或 pk = ANY() 一次刪除多條。示例:pk1 in (1,2) and pk2 = any('{3,4}') and pk3 = 5 ,刪除(1,3,5),(1,4,5),(2,3,5),(2,4,5)四條。

    • 同一列只能有一個條件(一模一樣的視為一個條件)。

    使用示例如下。

    BEGIN;
    CREATE TABLE test_delete (
        pk1 int,
        pk2 int,
        col1 int,
        col2 int,
        PRIMARY KEY (pk1, pk2)
    );
    COMMIT;
    
    --支持Fixed Plan,更多場景與Update樣例一致
    SET hg_experimental_enable_fixed_dispatcher_for_delete = ON;
    
    DELETE FROM test_delete
    WHERE pk1 = 1
        AND pk2 = 2;
    

SELECT場景

  • SELECT表達式

    SELECT時能進行Fixed Plan的表達式如下。

    SELECT
        col1,
        col2,
        col3,
    ...
    FROM
        TABLE
    WHERE
        pk1 = ?
        AND pk2 = ?
        AND pk3 = ?;
    
    • 支持Select內部表,不支持外部表。

    • 支持分區子表,不支持分區父表。

    • 表必須有主鍵(PK)。

  • 點查(key/value)場景

    點查場景支持的情況如下。

    • where條件里有且只能有全部的PK。

    • 可以使用pk in (?,?,?) 或 pk = ANY() 一次查多條。示例: pk1 in (1,2) and pk2 = any('{3,4}') and pk3 = 5,查(1,3,5),(1,4,5),(2,3,5),(2,4,5)四條。

    • 同一列只能有一個條件(一模一樣的視為一個條件)。

    • 如果有limit,limit的值必須>0

    使用示例如下。

    BEGIN;
    CREATE TABLE test_select (
        pk1 int,
        pk2 int,
        col1 int,
        col2 int,
        PRIMARY KEY (pk1, pk2)
    );
    CALL set_table_property ('test_select', 'orientation', 'row');
    COMMIT;
    
    --支持Fixed Plan
    SELECT * FROM test_select WHERE pk1 = 1 AND pk2 = 2;
  • PrefixScan場景

    • PrefixScan場景表達式

      PrefixScan場景是指表有多個主鍵,查詢時按照左匹配原則只查幾列主鍵,查詢表達式如下。

      SET hg_experimental_enable_fixed_dispatcher_for_scan = on;
      SELECT col1,col2,col3,... FROM TABLE WHERE pk1 = ? AND pk2 = ?;
      SELECT col1,col2,col3,... FROM TABLE WHERE pk1 = ? AND pk2 < ?;--從1.1.48版本開始支持pk最后一列條件為range
      SELECT col1,col2,col3,... FROM TABLE WHERE pk1 = ? AND pk2 BETWEEN ? AND ?;--從1.1.48版本開始支持pk最后一列條件為range                                
    • PrefixScan使用

      PrefixScan的使用條件如下。

      • 需要配置GUC參數:hg_experimental_enable_fixed_dispatcher_for_scan=on;,且實例在V1.3.35版本以上。

      • 表必須有Distribution Key,且where語句里必須包含所有的Distribution Key。

      • where語句里有且只有PK的Prefix。PrefixScan從V1.1.48版本開始支持主鍵最后一列條件設置為范圍(同時包含上限和下限)。

        說明

        Prefix定義: 若PK為(pk1,pk2,pk3),則(pk1),(pk1,pk2)為Prefix。

      • 僅行存表(包括行列共存)支持PrefixScan。

      • 同一列只能有一個條件(一模一樣的視為一個條件)。

      • 如果含有limit條件,limit的值必須大于0。

      說明

      PrefixScan一次性返回所有結果行,如果結果的字節數大于hg_experimental_fixed_scan_bytesize_limit會報錯:scan result size larger than fixed scan size limit ,可以通過配置hg_experimental_fixed_scan_bytesize_limit參數設置更符合場景的值,默認值為1048576,即1MB。

      示例如下,若表PK為(pk1,pk2,pk3,pk4), Distribution Key為pk1,pk3

      BEGIN;
      CREATE TABLE test_select_prefix (
          pk1 int,
          pk2 int,
          pk3 int,
          pk4 int,
          PRIMARY KEY (pk1, pk2, pk3, pk4)
      );
      CALL set_table_property ('test_select_prefix', 'orientation', 'row');
      CALL set_table_property ('test_select_prefix', 'distribution_key', 'pk1,pk3');
      COMMIT;
      
      --沒有包含所有distribution key,不能走fixed plan
      SELECT * FROM test_select_prefix WHERE pk1 = ? AND pk2 = ?;
      --不是pk的prefix,不能走fixed plan
      SELECT * FROM test_select_prefix WHERE pk1 = ? AND pk3 = ?;
      
      --可以走fixed plan
      SET hg_experimental_enable_fixed_dispatcher_for_scan = ON;
      
      SELECT * FROM test_select_prefix WHERE pk1 = ? AND pk2 = ? AND pk3 = ?;
      

      可以使用pk in (?,?,?)pk = ANY()一次性查多條,命令如下。

      pk1 IN (1,2) AND pk2 = 3 <=> scan(1,3),(2,3)兩組
      pk2 =any('{3,4}') AND pk1 IN (1,2) <=> scan(1,3),(1,4),(2,3),(2,4)四組
    • 使用示例

      BEGIN;
      CREATE TABLE test_scan (
          pk1 int,
          pk2 int,
          pk3 int,
          col1 int,
          PRIMARY KEY (pk1, pk2, pk3)
      );
      CALL set_table_property ('test_scan', 'orientation', 'row');
      CALL set_table_property ('test_scan', 'distribution_key', 'pk1,pk2');
      COMMIT;
      
      INSERT INTO test_scan
          VALUES (1, 2, 3, 4);
      
      --支持Fixed Plan
      SET hg_experimental_enable_fixed_dispatcher_for_scan = ON;
      
      SELECT * FROM test_scan WHERE pk1 = 1 AND pk2 = 2;
      
      --支持Fixed Plan
      SET hg_experimental_enable_fixed_dispatcher_for_scan = ON;
      
      SELECT * FROM test_scan WHERE pk1 = 1 AND pk2 IN (2, 3);
      
      --支持Fixed Plan
      SET hg_experimental_enable_fixed_dispatcher_for_scan = ON;
      
      SELECT * FROM test_scan WHERE pk1 = ANY ('{3,4}') AND pk2 IN (2, 3);
      
      --支持fixed plan,pk最后一列是range條件,需要1.1.48及以上版本支持
      SET hg_experimental_enable_fixed_dispatcher_for_scan = ON;
      
      SELECT * FROM test_scan WHERE pk1 = 1 AND pk2 = 1 AND pk3 > 1 AND pk3 < 4;
      
      --支持fixed plan,pk最后一列是range條件,需要1.1.48及以上版本支持
      SET hg_experimental_enable_fixed_dispatcher_for_scan = ON;
      
      SELECT * FROM test_scan WHERE pk1 = 1 AND pk2 = 1 AND pk3 BETWEEN 1 AND 4;
      
      --不包含所有的distribution key,不支持Fixed Plan
      SELECT * FROM test_scan WHERE pk1 = 1;
      
      --不符合主鍵前綴Prefix,不支持Fixed Plan
      SELECT * FROM test_scan WHERE pk2 = 2;

COPY場景

Hologres從1.3.17版本開始,COPY語句支持走Fixed Plan,與非Fixed Plan相比差異如下。

對比項

Fixed Plan

非Fixed Plan

鎖類型

行鎖

表鎖

數據可見行

寫入即可見。

Copy命令執行結束后可見。

性能

非常高

支持類型

TEXT或BINARY

TEXT

支持的主鍵沖突策略

支持如下策略:

  • NONE:主鍵發生沖突報錯。

  • IGNORE:主鍵發生沖突則對該數據執行跳過操作。

  • UPDATE:主鍵發生沖突則對該數據執行更新操作。

NONE(沖突則報錯)

COPY語句新增如下參數。

參數

說明

stream_mode

是否走Fixed Plan,取值如下。

  • true:走Fixed Plan。

  • false:不走Fixed Plan。

on_conflict

沖突策略,取值如下:

  • NONE:主鍵發生沖突報錯。

  • IGNORE:主鍵發生沖突則對該數據執行跳過操作。

  • UPDATE:主鍵發生沖突則對該數據執行更新操作。

命令示例如下。

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

非全列表現說明。

  • 如果Copy寫入的列不是全列,則為局部更新,表現如下:

    CREATE TABLE t0 (
        id int NOT NULL,
        name text,
        age int,
        PRIMARY KEY (id)
    );
    
    COPY t0 (id,
        name)
    FROM
        STDINWITH (stream_mode TRUE, on_conflict UPDATE);
    
    -- 上述COPY等價與如下
    INSERT INTOINSERT INTO t0 (id, name)
        VALUES (?, ?)
    ON CONFLICT (id)
        DO UPDATE SETid = excluded.id, name = excluded.name;
  • 如果Copy寫入的列不是全列,且未參與寫入的列設置了默認值屬性,表現如下:

    CREATE TABLE t0 (
        id int NOT NULL,
        name text,
        age int DEFAULT 0,
        PRIMARY KEY (id)
    );
    
    COPY t0 (id,
        name)
    FROM
        STDINWITH (stream_mode TRUE, on_conflict UPDATE);
    
    -- 上述COPY等價與如下INSERT INTO
    -- 若id數據不存在,age列賦值default value;
    -- 若id數據已存在,age列不更新
    INSERT INTO t0 (id, name, age)
        VALUES (?, ?, DEFAULT)
    ON CONFLICT (id)
        DO UPDATE SETid = excluded.id, name = excluded.name;
    

驗證Fixed Plan

  • 通過FixedPlan執行的更新類SQL,在控制臺的實時導入RPS面板中會顯示為SDK類型,包括INSERT、UPDATE和DELETE類型的操作。建議實時寫入類Insert、Update、Delete都盡量優化為Fixed Plan方案,改善數據更新的效率。RPS

  • 通過查看SQL執行計劃(explain sql),如果返回的執行計劃中含有FixedXXXNode,即表示觸發了Fixed Plan,如下圖所示。如未生成含有FixedXXXNode的執行計劃,請對照上文場景支持條件, 查看是否滿足條件。驗證fixedplan

性能調優

在某些場景上若是已經開啟Fixed Plan但還需要做性能調優時,可選擇如下方式。

  • Hologres V1.1.49版本開始針對Fixed Plan點查場景進行了優化,在大規模點查的情況下提升了30%以上吞吐。若有需要請升級實例至V1.1.49及以上版本。

  • 客戶端合理的攢批(使用Holo Client會自動攢批),即一次執行SQL命令的數量,實踐證明數量為512或者512的倍數性能會更好。

常見問題

  • 問題1:連接報錯:role/database does not exist.

    • 原因:用戶或DB不存在。

    • 解決辦法:檢查連接信息,填寫正確的用戶名或DB名。

      您可以登錄Hologres管理控制臺,單擊目標實例操作列中的管理,然后單擊數據庫管理,在用戶管理 DB 授權頁面獲取并確認用戶名或DB名。

  • 問題2:數據寫入過程中報錯:the requested table name: xxx (id: xx, version: xx) mismatches the version of the table (id: xx, version: xx) from server.

    • 原因:數據寫入過程中表元信息發生變化(如增加列)導致Table Version發生變化。

    • 解決方案:重新建立連接,Fixed Plan會獲取新的表元信息并進行寫入。