全部產品
Search
文件中心

Hologres:GUC參數

更新時間:Aug 25, 2026

為了更好地支援Hologres使用者豐富的使用情境,Hologres提供一些GUC參數。本文將介紹Hologres中GUC參數的含義以及如何使用。

使用限制

GUC參數對系統資料表不生效。

GUC參數一覽表

GUC名稱

適用情境

說明

使用樣本

hg_enable_start_auto_analyze_worker

開啟Auto Analyze,以及Auto Analyze相關配置,詳情請參見ANALYZE和AUTO ANALYZE。

HologresV1.1及以上版本預設開啟,值為on。

set hg_enable_start_auto_analyze_worker = on;

hg_auto_check_table_changes_interval

預設值為10min。

set hg_auto_check_table_changes_interval = '10min';

hg_auto_check_foreign_table_changes_interval

預設值為4h。

set hg_auto_check_foreign_table_changes_interval = '4h';

hg_auto_analyze_max_sample_row_count

預設值為16777216。

set hg_auto_analyze_max_sample_row_count = 16777216;

hg_fixed_api_modify_max_delay_interval

預設值為3d。

set hg_fixed_api_modify_max_delay_interval = '3day';

hg_foreign_table_max_partition_limit

查MaxCompute外部表格分區限制。如需調整限制可通過該GUC參數進行設定。

  • Hologres v3.0.7之前版本(不含),預設值為512,支援範圍為0-1024。

  • Hologres v3.0.7及以上版本,預設值為0,表示不作限制,支援範圍為0-1024。

set hg_foreign_table_max_partition_limit = 128;

hg_experimental_query_batch_size

MaxCompute效能調優參數,詳情請參見最佳化MaxCompute外部表格的查詢效能。

預設值為8192。

set hg_experimental_query_batch_size = 4096;

hg_foreign_table_split_size

預設值為64,不建議設定過大。

set hg_foreign_table_split_size = 128;

hg_foreign_table_executor_max_dop

預設值調整為與執行個體Core數相同,最大為128。

set hg_foreign_table_executor_max_dop = 32;

hg_foreign_table_executor_dml_max_dop

預設值為32。

set hg_foreign_table_executor_dml_max_dop = 16;

hg_enable_access_odps_orc_via_holo

HologresV1.1及以上版本預設開啟,值為on。

set hg_enable_access_odps_orc_via_holo = on;

hg_experimental_enable_result_cache

查詢結果緩衝。

預設值為on,不建議關閉。

set hg_experimental_enable_result_cache = on;

optimizer_join_order

內部效能調優參數,詳情請參見最佳化查詢效能。

預設值為exhaustive,後面可以接Query命令。

set optimizer_join_order = query;

optimizer_force_multistage_agg

預設值為off,按需開啟。

set optimizer_force_multistage_agg = on;

hg_anon_enable

資料脫敏函數,詳情請參見資料脫敏。

預設值為off,建議資料庫層級按需開啟。

alter database <DB_NAME> set hg_anon_enable = on;

hg_experimental_encryption_options

資料加密規格設定,詳情請參見資料存放區加密。

預設值為off,建議資料庫層級按需開啟。

alter database <DB_NAME> set hg_experimental_encryption_options='AES256,623c26ee-xxxx-xxxx-xxxx-91d323cc4855,AliyunHologresEncryptionDefaultRole,187xxxxxxxxxxxxx';

statement_timeout

活躍query逾時時間,詳情請參見管理Query。

預設值為8h,建議根據業務情況,session層級設定不同粒度的逾時時間。

set statement_timeout = 5000 ;

idle_in_transaction_session_timeout

空閑事務的逾時時間,詳情請參見管理Query。

預設值為10min,建議資料庫層級設定,否則當事務泄漏時容易造成死結。

alter database db_name set idle_in_transaction_session_timeout=300000;

idle_session_timeout

自動釋放空閑連線逾時時間,詳情請參見串連數管理。

預設值為0,即不會自動釋放。建議設定,否則串連數太多導致超過執行個體預設上限,從而無法串連。

alter database <DB_NAME> SET idle_session_timeout = 600000;

hg_experimental_functions_use_pg_implementation

時間範圍擴充。to_char、to_date和to_timestamp函數在處理時間類型時預設範圍為1925-2282,通過設定GUC參數支援0000-9999年的時間,詳情請參見類型轉換函式。

HologresV1.1.31版本開始支援,設定後支援時間範圍為0000-9999。

set hg_experimental_functions_use_pg_implementation = 'to_char';

hg_experimental_approx_count_distinct_precision

調整APPROX_COUNT_DISTINCT誤差率,詳情請參見APPROX_COUNT_DISTINCT。

預設值為17,取值範圍為12-20。

set hg_experimental_approx_count_distinct_precision = 20;

timezone

時區設定。

預設值為PRC(東八區)。

set timezone='GMT-8:00';

hg_experimental_enable_create_table_like_properties

複製表時同時複製表屬性(主鍵、索引等),詳情請參見CREATE TABLE LIKE。

預設值為off。

set hg_experimental_enable_create_table_like_properties=true;

hg_experimental_affect_row_multiple_times_keep_first

使用insert on conflict,來源資料重複時資料保留原則,詳情請參見INSERT ON CONFLICT(UPSERT)。

預設值為off。

set hg_experimental_affect_row_multiple_times_keep_first = on;

hg_experimental_affect_row_multiple_times_keep_last

set hg_experimental_affect_row_multiple_times_keep_last = on;

hg_experimental_enable_read_replica

單一實例多副本高可用以及相關配置,詳情請參見單一實例Shard級多副本。

預設值為on。

set hg_experimental_enable_read_replica = on;

hg_experimental_display_query_id

通過NOTICE訊息在用戶端列印Query ID,用於在hologres.hg_query_log中精確定位Query並排查問題。適用於HoloWeb、PSQL、JDBC、Python(Psycopg)等各類用戶端,詳情請參見擷取Query ID。

預設值為off。Query ID通過NOTICE訊息返回,而非結果集中的一列,程式化用戶端需註冊相應的NOTICE回調才能擷取。

set hg_experimental_display_query_id = on;

查看當前GUC參數的狀態或預設值

通過show命令語句可以查看某個GUC參數的狀態或者預設值,使用樣本如下。

  • 查看是否開啟Auto Analyze。

    show hg_enable_start_auto_analyze_worker;
  • 查看讀取MaxCompute分區限制大小。

    show hg_foreign_table_max_partition_limit;
  • 查看是否開啟Query ID回顯。

    show hg_experimental_display_query_id;

設定GUC參數

GUC在使用時,可以設定為session層級或者資料庫層級生效。

說明

具體是session層級還是資料庫層級,需要根據業務情境以及參數的詳情合理評估,不建議所有的參數都設定為資料庫層級。

  • session層級

    通過set命令可以在session層級設定GUC參數。session層級的參數只在當前session生效,當串連斷開之後,將會失效,建議加在SQL前一起執行。

    • 文法樣本如下。

      set <GUC_NAME> = <VALUE>;

      GUC_NAME為GUC參數的名稱,VALUE為GUC參數的值。

    • 使用樣本如下。

      -- 開啟Auto Analyze
      set hg_enable_start_auto_analyze_worker = on;
      
      -- 讀取MaxCompute的分區限制變為1024
      set hg_foreign_table_max_partition_limit =1024;
      
      -- 開啟Query ID回顯
      set hg_experimental_display_query_id = on;
  • 資料庫層級

    可以通過alter database xx set xxx命令來設定DB層級的GUC參數,執行完成後在整個DB層級生效,無需重啟執行個體。設定完成後當前串連需要重新中斷連線才會生效,後續建立串連會自動繼承此參數配置。建立DB不會生效,需要重新手動設定。

    • 文法樣本如下。

      alter database <DB_NAME> set <GUC_NAME> = <VALUE>;

      DB_NAME為資料庫名稱,GUC_NAME為GUC參數的名稱,VALUE為GUC參數的值。

    • 使用樣本如下。

      -- DB層級開啟Auto Analyze
      alter database testdb set hg_enable_start_auto_analyze_worker = on;
      
      -- DB層級讀取MaxCompute的分區限制變為1024
      alter database testdb set hg_foreign_table_max_partition_limit =1024;

擷取Query ID

Query ID是Hologres中每條Query的唯一標識,也是慢Query日誌hologres.hg_query_log的主鍵之一。擷取某條SQL對應的Query ID後,即可精確反查該Query的耗時、狀態、讀取行數等執行詳情,是問題排查的關鍵入口。

Query ID預設不返回給用戶端。開啟hg_experimental_display_query_id後,服務端會在執行SQL時通過NOTICE訊息將Query ID回顯給用戶端。

參數說明

專案

說明

參數名稱

hg_experimental_display_query_id

作用

執行SQL時通過NOTICE訊息在用戶端列印Query ID。

預設值

off

取值

on或off。

生效粒度

session層級或資料庫層級。

返回形式

NOTICE訊息,格式為QueryID: <QUERY_ID>,例如QueryID: 1002002606817130830。

使用該參數時,請注意以下兩項機制:

  • Query ID通過NOTICE訊息返回,而非結果集中的一列。在程式化用戶端中,僅讀取查詢結果(如fetchall())無法擷取Query ID,必須通過用戶端驅動提供的NOTICE擷取機制讀取。

  • 該參數按session生效,串連斷開後失效,每建立一個新串連都需要重新設定一次。使用串連池時需特別注意,應將set語句配置到串連初始化環節,詳情請參見串連池情境。

開啟Query ID回顯

-- session層級開啟,建議與業務SQL一起執行
set hg_experimental_display_query_id = on;

-- 查看目前狀態
show hg_experimental_display_query_id;

-- 資料庫層級開啟,對該資料庫的建立串連生效,已有串連需重建立立
alter database <DB_NAME> set hg_experimental_display_query_id = on;

在用戶端中擷取Query ID

Java(JDBC)

在JDBC中,NOTICE以SQLWarning鏈的形式返回,需要在SQL執行後通過statement.getWarnings()遍曆擷取並解析出Query ID,結果集ResultSet中不包含Query ID。完整樣本如下。

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLWarning;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class HologresQueryIdDemo {

    // 匹配NOTICE中的 "QueryID: <QUERY_ID>"
    private static final Pattern QUERY_ID_PATTERN = Pattern.compile(
            "query[_ ]?id\\s*(?:is\\b|[=:])?\\s*([0-9a-zA-Z_\\-]{6,})", Pattern.CASE_INSENSITIVE);

    public static void main(String[] args) throws Exception {
        // Endpoint請選擇與運行環境匹配的網路地址(公網或VPC),在控制台的執行個體詳情頁擷取
        String url = "jdbc:postgresql://<ENDPOINT>:80/<DB_NAME>";
        String user = "<ACCESS_KEY_ID>";
        String password = "<ACCESS_KEY_SECRET>";

        try (Connection conn = DriverManager.getConnection(url, user, password);
             Statement stmt = conn.createStatement()) {

            // 開啟Query ID回顯,該參數預設為off且僅在當前session生效
            stmt.execute("set hg_experimental_display_query_id = on;");

            String sql = "select count(*), sum(id) from holo_query_id_demo;";

            // 執行前清空上一條SQL殘留的Warning,確保Query ID與SQL一一對應
            stmt.clearWarnings();
            boolean hasResultSet = stmt.execute(sql);

            // 讀取結果集,Query ID不在結果集中
            if (hasResultSet) {
                try (ResultSet rs = stmt.getResultSet()) {
                    while (rs.next()) {
                        System.out.println("rows      : (" + rs.getLong(1) + ", " + rs.getLong(2) + ")");
                    }
                }
            }

            // NOTICE以SQLWarning鏈的形式返回,遍曆並解析出Query ID
            String queryId = null;
            List<String> notices = new ArrayList<>();
            for (SQLWarning w = stmt.getWarnings(); w != null; w = w.getNextWarning()) {
                notices.add(w.getMessage());
                Matcher m = QUERY_ID_PATTERN.matcher(w.getMessage());
                if (m.find()) {
                    queryId = m.group(1);
                }
            }

            System.out.println("query_id  : " + queryId);
            System.out.println("notices   : " + notices);
        }
    }
}

返回結果樣本如下。

rows      : (1000, 500500)
query_id  : 1002002606817139331
notices   : [One or more columns in the following table(s) do not have statistics: holo_query_id_demo, QueryID: 1002002606817139331]

使用時請注意以下三點:

  • PreparedStatement的用法相同,執行後調用pstmt.getWarnings()遍曆即可。

  • 每次執行新的SQL前先調用clearWarnings(),否則Warning會在同一Statement對象上累積,導致Query ID與SQL無法一一對應。

  • NOTICE中可能混有其他訊息(例如統計資訊缺失的提示),解析時應按QueryID:首碼匹配。

Python(Psycopg 3)

Hologres相容PostgreSQL 11,推薦使用Psycopg 3驅動(通過pip install "psycopg[binary]"安裝)。NOTICE需通過conn.add_notice_handler()註冊回調擷取,cur.fetchall()的返回結果中不包含Query ID。完整樣本如下。

import re
import psycopg

NOTICES = []
QUERY_IDS = []

QUERY_ID_PATTERN = re.compile(
    r"query[_ ]?id\s*(?:is\b|[=:])?\s*([0-9a-zA-Z_\-]{6,})", re.IGNORECASE
)

def notice_handler(diag):
    """服務端每發送一條NOTICE都會回調一次,從中解析Query ID。"""
    text = diag.message_primary or ""
    NOTICES.append(text)
    match = QUERY_ID_PATTERN.search(text)
    if match:
        QUERY_IDS.append(match.group(1))

conn = psycopg.connect(
    host="<ENDPOINT>",          # 在控制台的執行個體詳情頁擷取
    port=80,
    dbname="<DB_NAME>",
    user="<ACCESS_KEY_ID>",
    password="<ACCESS_KEY_SECRET>",
)
conn.autocommit = True
conn.add_notice_handler(notice_handler)   # 註冊NOTICE回調

cur = conn.cursor()
# 開啟Query ID回顯,該參數預設為off且僅在當前session生效
cur.execute("set hg_experimental_display_query_id = on;")

def run_sql(sql, params=None, fetch=True):
    """執行SQL並返回 (結果集, Query ID, 原始NOTICE列表)。無結果集時結果集為None。"""
    NOTICES.clear()
    QUERY_IDS.clear()
    cur.execute(sql, params)
    rows = None
    if fetch and cur.description is not None:
        rows = cur.fetchall()
    query_id = QUERY_IDS[-1] if QUERY_IDS else None
    return rows, query_id, list(NOTICES)

rows, query_id, notices = run_sql("select count(*) from holo_query_id_demo;")
print("rows:", rows)
print("query_id:", query_id)

返回結果樣本如下,DML與DQL均可擷取Query ID。

SQL       : insert into holo_query_id_demo select i, 'v' || i from generate_series(1, 1000) i;
query_id  : 1002002606817130830
notices   : ['QueryID: 1002002606817130830']

SQL       : select count(*), sum(id) from holo_query_id_demo;
query_id  : 1002002606817139331
rows      : [(1000, 500500)]
notices   : ['One or more columns in the following table(s) do not have statistics: holo_query_id_demo', 'QueryID: 1002002606817139331']

串連池情境

該參數按session生效,每條物理串連都需要設定一次。使用串連池時,應將set語句配置到串連建立(初始化)環節,而不是在每次查詢前手動執行。

Python以psycopg_pool為例,樣本如下。

# 需先執行 pip install psycopg_pool
from psycopg_pool import ConnectionPool

def configure(conn):
    conn.autocommit = True
    conn.add_notice_handler(notice_handler)
    conn.execute("set hg_experimental_display_query_id = on;")

pool = ConnectionPool(kwargs=CONN_INFO, configure=configure, min_size=1, max_size=4)

with pool.connection() as conn:
    conn.execute("select 1;").fetchall()

Java通過串連池的初始化SQL配置,保證每條物理串連建立時都已開啟該參數。以HikariCP和Druid為例,樣本如下。

// HikariCP:connectionInitSql在每條物理串連建立時執行
HikariConfig config = new HikariConfig();
config.setJdbcUrl(url);
config.setUsername(user);
config.setPassword(password);
config.setConnectionInitSql("set hg_experimental_display_query_id = on;");
HikariDataSource dataSource = new HikariDataSource(config);

// Druid:connectionInitSqls支援配置多條初始化SQL
DruidDataSource druid = new DruidDataSource();
druid.setUrl(url);
druid.setUsername(user);
druid.setPassword(password);
druid.setConnectionInitSqls(Collections.singletonList("set hg_experimental_display_query_id = on;"));

從串連池擷取串連後,仍需在每次執行SQL後通過statement.getWarnings()擷取Query ID,擷取方式請參見Java(JDBC)。

通過Query ID反查執行詳情

擷取Query ID後,可在慢Query日誌中按query_id精確定位該Query的耗時、狀態、讀取行數等資訊。

select query_id, status, duration, query_start, application_name, command_tag
from hologres.hg_query_log
where query_id = '<QUERY_ID>';

hologres.hg_query_log存在約1分鐘的寫入延遲,Query剛執行完可能查詢不到,請稍後重試。

注意事項

  • 該參數按session生效,串連斷開後失效。每建立一個新串連都必須重新執行set hg_experimental_display_query_id = on;,否則該串連上的Query不會回顯Query ID。

  • 並非所有語句都會返回Query ID。DDL語句(如CREATE TABLE、DROP TABLE)以及不涉及計算引擎的簡單查詢(如select 1;)不返回Query ID,屬於預期行為;DML語句(如INSERT)與常規查詢(如SELECT)可正常返回。

  • NOTICE中可能同時包含其他提示訊息(例如統計資訊缺失的警告),程式解析時應按QueryID:首碼精確匹配,避免誤取。

無法擷取Query ID時如何排查

請按以下順序確認。

  1. 執行show hg_experimental_display_query_id;確認參數是否為on。若為off,說明當前串連未執行過set(使用串連池時可能已切換到其他串連),請重新設定或檢查串連初始化邏輯。

  2. 檢查NOTICE緩衝區是否為空白。若為空白,說明服務端未發送NOTICE,請確認執行個體版本是否支援該參數,或確認該語句類型是否會產生Query ID。

  3. 若NOTICE有內容但未解析出Query ID,說明訊息措辭與解析規則不匹配,請列印NOTICE原始文本,並按執行個體實際返回的格式調整解析邏輯。

  4. 使用串連池時,請確認set語句已配置到串連初始化環節,保證每條物理串連都已執行。