ANALYZE和AUTO ANALYZE

更新時間:
Copy as MD

本文檔介紹HologresANALYZE命令,以及AUTO ANALYZE後台自動收集統計資訊的行為,並對主要行為參數進行說明,便於您更清楚地瞭解和控制統計資訊的收集行為,提高查詢計劃品質。

統計資訊與 ANALYZE 概述

為什麼需要統計資訊?

最佳化器依賴表和列的統計資訊來產生合理的執行計畫,包括:

  • 行數、列數

  • 列寬度(Width)

  • 非重複值個數(Number of Distinct Values,NDV)

  • 最常見值(Most Common Values,MCV)及其頻率

  • 長條圖(Histogram)以及其他分布特徵

這些資訊將指導最佳化器:

  • 估算運算元執行開銷(Cost)

  • 裁剪執行計畫搜尋空間

  • 選擇合適的 Join 順序和 Join 演算法

  • 估算記憶體和並行度

從而產生更優的執行計畫。

ANALYZE 命令是使用者主動收集表/列統計資訊的標準手段。在缺乏統計資訊或統計不準確時,查詢計劃可能明顯退化,例如Join 順序異常,進而表現為:Query發生OOM、執行時間長、執行個體CPU消耗高等。

AUTO ANALYZE 功能是Hologres系統自動收集表/列統計資訊的標準方式。由於AUTO ANALYZE是後台非同步系統行為,從表的資料變化,到 AUTO ANALYZE 發現、調度、完成統計資訊自動收集,是有二位元秒級~分鐘級的延遲,因此在一些特殊情境下,推薦使用者自行手動 ANALYZE,以確保統計資訊被及時收集。

什麼時候需要手動執行 ANALYZE

推薦在以下情境手動執行:

  • 表上執行了 INSERT / UPDATE / DELETE 操作,匯入/更新/刪除了大量資料之後,立即要被查詢,推薦在INSERT / UPDATE / DELETE之後對錶進行一次 ANALYZE;

  • 多表 Join 效能明顯下降時,在關鍵 Join 列、Group By 列上執行列級 ANALYZE;

  • 執行外表的 CREATE FOREIGN TABLE 或者 IMPORT FOREIGN SCHEMA 後,立即要被查詢,推薦查詢前對建立外表執行一次 ANALYZE 收集初始統計;

  • 執行 CREATE EXTERNAL DATABASE 後,立即要被查詢,推薦查詢前對外部資料庫下需要查詢的表執行 ANALYZE;

  • 出現以下報錯/表現之一:

    • 多表 Join OOM報錯:Query executor exceeded total memory limitation ...,或者Query exceed per query memory limitation ...

    • 多表 Join 報錯:Capacity error: BinaryArray cannot contain more than 2147483646 bytes ...

    • 匯入或查詢任務已耗用時間異常長且 CPU 使用率不均衡。

    • EXPLAIN <SQL> 發現某個Scan運算元的行數預估為1000,-> Seq Scan on tbl (cost=0.00..5.00 rows=1000 width=1);說明表缺乏統計資訊。

    • EXPLAIN <SQL> 發現某個Scan運算元的行數預估為1,-> Seq Scan on tbl (cost=0.00..1.00 rows=1 width=1);說明表預估為0行,如果該Scan實際不為0行,則可能為統計資訊過時,推薦進行一次手動 ANALYZE。

在上述情境中,通常建議先手動 ANALYZE 再觀察是否恢複,再結合 AUTO ANALYZE 配置做進一步調優。

ANALYZE 命令

基本文法與行為

  • 收集整表所有列的統計資訊

ANALYZE table_name;
  • 收集錶行數,以及對錶中所有普通列統一收集:Width、MCV、Histogram、NDV 等統計資訊;

  • 採用基於採樣的方式估算各類統計值,採樣操作會在 ANALYZE 內部發起一個採樣子SQL。

  • ANALYZE 預設從表中隨機採樣30000行,做統計資訊收集與計算,不足30000行則全采。

  • 僅收集指定列的統計資訊(推薦對關鍵列使用)

ANALYZE table_name(col1, col2, ...);
  • 對指定列額外計算更精確的 NDV(通常採用 APPROX_COUNT_DISTINCT 邏輯獲得),較整表採樣更準確,但開銷更大;

  • MCV、Histogram、Width 等仍然通過採樣獲得;

  • 多次對同一列執行 ANALYZE 時,後一次會覆蓋該列的舊統計資訊,但不會影響其他未指定列。

對於具有多列的表,ANALYZE table_name; 不完全等價於 ANALYZE table_name(col1, col2, ...):後者在 NDV 上通常更精確,但代價更高。推薦對常用 Join 列、Group By 列等關鍵列執行列級 ANALYZE 作為補充。

限制與注意事項

  • 哪些列不會被 ANALYZE

    • 類型不支援:列類型為使用者自訂類型(User Defined Type),或不在 Hologres 支援統計的類型集合內時,會跳過統計資訊的收集:

      • 不支援 ANALYZE 的列類型包括:"char"(單字元類型),BIT,VARBIT,BYTEA,NAME,JSON,TSVECTOR,TSQUERY,OID,XID,CID,INET,POINT,LINE, LSEG,BOX,CIRCLE,PATH,POLYGON,BITARRAY,VARBITARRAY,BYTEAARRAY,INT2ARRAY,MONEYARRAY,NUMERICARRAY,TIMEARRAY,TIMETZARRAY,TIMESTAMPTZARRAY,TIMESTAMPARRAY,ANYARRAY,REGCLASS,DATEARRAY或其他INTERNAL類型。

      • 當列類型不支援時,無論手動 ANALYZE 還是 AUTO ANALYZE,都會被忽略;

      • 對於分區表而言,不支援增量式分區統計資訊合并的列類型,也不會被ANALYZE。不支援的類型除了上述類型之外,還包括:BOOLARRAY,INT4ARRAY,TEXTARRAY,BPCHARARRAY,VARCHARARRAY,INT8ARRAY,FLOAT4ARRAY,FLOAT8ARRAY。

    • 被標記為刪除的列ALTER TABLE ... DROP COLUMN 後保留的邏輯列(attisdropped = true)不會被 ANALYZE;

    • 按列屬性顯式禁用

      • 設定了列屬性enable_analyze = false的列,不會被 ANALYZE 和 AUTO ANALYZE;

      • 設定了列屬性enable_auto_analyze = false的列,不會被 AUTO ANALYZE。

      • 關於上述列屬性,詳見後續章節。

    • JSONB 列未開啟統計

      • 若列類型為 JSONB,且未開啟 enable_jsonb_stats,則該列不會收集 JSONB 統計資訊;

      • 如需依賴 JSONB 列的統計(例如複雜 JSON 過濾條件),需要先在列屬性中開啟 enable_jsonb_stats

小結:即使執行了 ANALYZE table_name;,上述列也可能因為類型或列屬性的限制而被跳過,當pg_stats 中看不到對應統計記錄時,可優先從這些限制排查。

  • 資料湖表的ANALYZE限制

    • 不支援對具體Timestamp、Version、Branch、SnapshotTag單獨ANALYZE

典型用法

  • 典型推薦用法

    • 對 Join 列、Group By 列、過濾條件列執行列級 ANALYZE:

ANALYZE tablename (order_id, user_id, dt);
    • 匯入或批次更新後,對受影響較大的表執行:

ANALYZE tablename;
    • 對外部表格(FOREIGN TABLE / IMPORT FOREIGN SCHEMA / EXTERNAL DATABASE 下的表)在首次查詢前執行:

ANALYZE foreign_table;
  • 通過設定列屬性,跳過特定列的統計收集

    • Hologres 支援通過列級屬性控制是否對某列執行 ANALYZE 或 AUTO ANALYZE,適用於以下情境:

      • 超寬列(如超長 Text 等)統計開銷大,收集它的統計資訊對查詢計劃協助有限,甚至完全無用;

      • 某些列從不參與 Join、過濾或彙總,無需收集統計資訊;

      • 需要減少 ANALYZE 或 AUTO ANALYZE 的資源消耗。

    • 控制參數為以下column options:

      • enable_analyze:控制該列是否參與手動 ANALYZE 和自動 AUTO ANALYZE,預設為 true

      • enable_auto_analyze:僅控制該列是否參與自動 AUTO ANALYZE,預設為 true

    • 設定方式(通過 ALTER TABLE 命令):

-- 禁用某列的 ANALYZE 和 AUTO ANALYZE
ALTER TABLE t ALTER COLUMN bitmap_col SET (enable_analyze = false);

-- 禁用某列的 AUTO ANALYZE,但仍允許手動 ANALYZE
ALTER TABLE t ALTER COLUMN large_text_col SET (enable_auto_analyze = false);

-- 恢複預設行為(重新啟用)
ALTER TABLE t ALTER COLUMN bitmap_col RESET (enable_analyze);
ALTER TABLE t ALTER COLUMN large_text_col RESET (enable_auto_analyze);
    • 注意事項:

      • 設定 enable_analyze = false 後,該列在執行 ANALYZE table_name; 時會被自動跳過,但仍可通過手動 ANALYZE table_name(col); 顯式收集;

      • 設定 enable_auto_analyze = false 後,該列不會被 AUTO ANALYZE 收集,但仍可通過手動 ANALYZE table_name(col); 顯式收集;

      • 如果某列對查詢計劃有重要影響(如 Join 列、過濾條件列),不建議禁用其統計收集。

分區表與增量式分區 ANALYZE

為了降低對大分區表執行 ANALYZE 的開銷,Hologres 支援增量式分區 ANALYZE:

  • 目標

    • 不再每次對分區父表進行全量採樣;

    • 通過對子分區 ANALYZE + 合并統計資訊的方式更新父表統計資訊;

    • 對未發生變化的分區子表不再重複統計。

情境與限制

  • Hologres V2.0版本及以上,預設開啟增量式分區ANALYZE,無需手動開啟。具體請以產品版本說明為準;

  • 啟用後,對某個分區子表執行 ANALYZE 時,會嘗試聯合其他子表的統計資訊,合并出父表統計資訊;

  • 能合并出父表統計資訊的必要條件是:除當前 ANALYZE 的子表以外,該父表下所有其他子表均已有統計資訊(包括行數統計資訊,和列統計資訊);

  • 因此,您可以:

    • 初次上線時,先對父表執行一次 ANALYZE,會自動檢測需要ANALYZE的子表並逐個ANALYZE,最終合并出分區父表統計資訊;

    • 後續新增分區時,只需對新增的子表執行 ANALYZE 即可。

簡要樣本

BEGIN;
DROP TABLE IF EXISTS t_parent;
CREATE TABLE t_parent(a int, b int) PARTITION BY LIST (a);
CREATE TABLE child1 PARTITION OF t_parent FOR VALUES IN (1);
CREATE TABLE child2 PARTITION OF t_parent FOR VALUES IN (2);
COMMIT;
insert into child1 values (1, 1), (1, 1), (1, 1), (1, 1), (1, 1), (1, 1), (1, 1), (1, 1), (1, 1), (1, 2);
insert into child2 values (2, 1), (2, 2), (2, 3), (2, 4), (2, 5), (2, 5), (2, 5), (2, 5), (2, 5), (2, 5);

-- child2缺乏統計資訊,無法合并出父表統計資訊
dbname=# ANALYZE child1;
INFO:  auto merging of leaf partition stats to calculate root partition stats is not possible because partition child2 is not analyzed
ANALYZE

-- child1已具備統計資訊,ANALYZE child2後,即可自動合并出父表統計資訊
dbname=# ANALYZE child2;
ANALYZE

dbname=# SELECT tablename,
       attname,
       null_frac         AS "NF",
       avg_width,
       n_distinct,
       most_common_vals  AS "MCV",
       most_common_freqs AS "MCV_FRAQ"
FROM   pg_stats
WHERE  tablename = 't_parent';

 tablename | attname | NF | avg_width | n_distinct |  MCV  |  MCV_FRAQ
-----------+---------+----+-----------+------------+-------+------------
 t_parent  | a       |  0 |         4 |          2 | {1,2} | {0.5,0.5}
 t_parent  | b       |  0 |         4 |       -0.2 | {1,5} | {0.45,0.3}
(2 rows)

-- 此後新增分區,ANALYZE子表,僅需要對子表採樣,即可自動合并出父表統計資訊。

ANALYZE 分區父表

有時分區表的多個子表都發生了資料變化,不想逐個 ANALYZE 子表,那麼可以針對父表做一次 ANALYZE。

當增量式分區 ANALYZE 被啟用的情況下,手動執行分區父表的 ANALYZE 時,系統會自適應地篩選需要更新統計資料的子表,而非盲目地對所有子表進行一遍 ANALYZE。這一機制可顯著降低大分區表的 ANALYZE 開銷,同時確保統計資訊的準確性。

行為說明

執行 ANALYZE partition_parent_table; 時,系統會自動識別以下兩類子表,並優先對其進行ANALYZE統計收集,再統一合并出父表的統計資訊:

  1. 統計資訊變化的子表(stats-changed partitions)

    • 子表資料自上次 ANALYZE 以來發生了顯著變化(插入、更新、刪除);

    • 判斷依據:

      • 資料變更行數達到變更閾值(1% * 上次的錶行數)。

  2. 無法合并統計資訊的子表(unable-to-merge partitions)

    • 子表缺失完整的統計資訊,導致無法參與父表統計資訊合并;

    • 常見原因包括:

      • 從未執行過 ANALYZE:子表統計資訊完全缺失;

      • 列統計資訊缺失:指定列缺少必要的統計資訊(如 MCV、Histogram、NDVHLL Counter);

      • 統計資訊與列類型不符:子表列類型發生變更,導致已有統計資訊與當前列類型不一致;

      • 統計資訊版本過舊:父表的統計資訊版本(statistic_version)低於最新子表的統計資訊版本,說明父表統計資訊不是最新,需要重新合并。

執行樣本與輸出

-- 對分區父表執行 ANALYZE
ANALYZE partition_parent_table;

典型輸出提示:

INFO:  will analyze 5 part tables first (stats changed 3, unable-to-merge 2)

此輸出表示:

  • 系統識別出 5 個子表需要優先統計;

  • 其中 3 個子表因資料變更較多,需要觸發統計資訊更新;

  • 其中 2 個子表因缺失或停用統計資訊被標記為無法合并,需要內部先觸發一次 ANALYZE。

注意事項

  • 不建議對分區子表設定 autovacuum_enabled = false(表層級關閉 AUTO ANALYZE),否則可能導致該子表長期處於「無法合并」狀態,除非再次手動 ANALYZE 該子表。

通過這一機制,Hologres 能夠在保障統計資訊品質的前提下,顯著提升大分區表 ANALYZE 的執行效率,為查詢最佳化工具提供更及時、準確的決策依據。

邏輯分區表的ANALYZE

邏輯分區表(Logical Partitioned Table)是 Hologres 特有的分區表類型,與標準的 PostgreSQL 分區表(通過 PARTITION BY 建立物理子表)不同,邏輯分區表在物理上仍為單張表,僅在邏輯層面通過分區列值進行分區劃分,提供了更靈活的分區管理能力。

邏輯分區表的ANALYZE邏輯,和物理分區表基本一致。唯一的區別是,邏輯分區表的子分區,不是一個單獨的表,但它們和物理分區子表一樣,仍然都有自己單獨的行數統計資訊和列統計資訊等。

行為說明

對邏輯分區表執行 ANALYZE 時,系統採用與物理分區表類似但獨立的處理邏輯:

  1. 自動探索邏輯分區

    • 對邏輯分區(父)表執行 ANALYZE logical_partitioned_table; 時,系統會自動從儲存引擎查詢該表的所有邏輯分區;

  2. 自適應篩選需要統計的邏輯分區

    • 與物理分區表類似,系統會識別以下邏輯分區並優先對其進行統計:

    • 統計資訊變化的子表(stats-changed partitions)

      • 子表資料自上次 ANALYZE 以來發生了顯著變化(插入、更新、刪除),判斷依據同前述物理分區表;

      • 缺失統計資訊的邏輯分區:從未執行過 ANALYZE,或指定列缺少必要統計資訊(如 HLL 計數器);

      • 統計資訊停用邏輯分區:列統計資訊與當前列類型不符,或統計資訊過時。

    • 跳過空分區:行數為 0 的邏輯分區會被自動忽略。

    • 系統輸出提示資訊,例如:

    INFO:  will analyze 10 logical partitions first
  3. 逐分區採樣與統計收集

    • 對每個需要統計的邏輯分區,系統構造帶有分區列過濾條件的採樣查詢(如 WHERE user_id = 1 AND event_date = '2024-11-04');

    • 在該邏輯分區範圍內進行資料採樣,收集列級統計資訊(NDV、MCV、Histogram、HLL 計數器等);

    • 統計資訊以邏輯分區為粒度儲存在 hologres_statistic.hg_table_statistic 中,通過 unique_name 欄位區分不同邏輯分區。

  4. 合并父表統計資訊

    • 當所有邏輯分區的統計資訊收集完成後,系統自動觸發統計資訊合并,產生父表統計資訊。

執行樣本與輸出

樣本 1:對邏輯分區父表執行 ANALYZE

-- 建立邏輯分區表
CREATE TABLE user_events (
    user_id INT NOT NULL,
    event_type TEXT NOT NULL,
    event_date DATE NOT NULL,
    event_data INT
)
LOGICAL PARTITION BY LIST(user_id, event_date);

-- 插入不同邏輯分區的資料
INSERT INTO user_events SELECT 1, 'login', '2024-11-01', i FROM generate_series(1, 1000) i;
INSERT INTO user_events SELECT 1, 'logout', '2024-11-02', i FROM generate_series(1, 1000) i;
INSERT INTO user_events SELECT 2, 'purchase', '2024-11-03', i FROM generate_series(1, 1000) i;
INSERT INTO user_events SELECT 3, 'view', '2024-11-04', i FROM generate_series(1, 1000) i;

-- 對父表執行 ANALYZE
ANALYZE VERBOSE user_events;

典型輸出:

INFO:  will analyze 4 logical partitions first
INFO:  analyzing hologres table "public.user_events" PARTITION (user_id=1,event_date='2024-11-01')
INFO:  analyzing hologres table "public.user_events" PARTITION (user_id=1,event_date='2024-11-02')
INFO:  analyzing hologres table "public.user_events" PARTITION (user_id=2,event_date='2024-11-03')
INFO:  analyzing hologres table "public.user_events" PARTITION (user_id=3,event_date='2024-11-04')
INFO:  try to merge root partition
INFO:  automatically merging leaf partition stats to calculate root partition stats

說明:

  • 系統自動探索了 4 個邏輯分區需要更新統計資料;

  • 逐個對每個邏輯分區進行統計收集;

  • 最後自動合并產生父表的全域統計資訊。

樣本 2:對指定邏輯分區執行 ANALYZE

-- 對單個邏輯分區執行 ANALYZE
ANALYZE user_events PARTITION (user_id=1, event_date='2024-11-01');

-- 對多個邏輯分區執行 ANALYZE
ANALYZE user_events
    PARTITION (user_id=1, event_date='2024-11-01')
    PARTITION (user_id=2, event_date='2024-11-03');

-- 對指定邏輯分區的特定列執行 ANALYZE
ANALYZE user_events
    PARTITION (user_id=1, event_date='2024-11-01') (user_id, event_type);

說明:

  • 可以使用 PARTITION 子句指定要統計的邏輯分區;

  • 支援同時指定多個邏輯分區;

  • 與標準 ANALYZE 一樣,可以進一步指定要統計的列。

統計資訊儲存

邏輯分區表的統計資訊儲存在 hologres_statistic.hg_table_statistic 表中:

SELECT
    unique_name,
    schema_name,
    table_name,
    total_rows,
    sample_rows,
    nattr
FROM hologres_statistic.hg_table_statistic
WHERE table_name = 'user_events'
ORDER BY unique_name;

結果樣本:

| unique_name | schema_name | table_name | total_rows | sample_rows | nattr |
|-------------|-------------|------------|------------|-------------| ----- |
| user_events | public | user_events | 4000 | 0 | 4 |
| user_events.a1b2c3d4e5f6... | public | user_events | 1000 | 1000 | 4 |
| user_events.f6e5d4c3b2a1... | public | user_events | 1000 | 1000 | 4 |
| user_events.1234567890ab... | public | user_events | 1000 | 1000 | 4 |
| user_events.abcdef123456... | public | user_events | 1000 | 1000 | 4 |

欄位說明:

  • 父表記錄

    • total_rows = 4000:所有邏輯分區的總行數;

    • sample_rows = 0:父表統計資訊通過合并得出,未直接採樣。

  • 邏輯分區記錄unique_name 包含統計資訊對象(表/分區)標識的 MD5 雜湊):

    • 每個邏輯分區有獨立的統計資訊記錄;

    • sample_rows = 1000:該邏輯分區實際採樣的行數。

邏輯分區表 ANALYZE 最佳實務

  1. 優先對邏輯分區父表執行 ANALYZE

    • 對邏輯分區父表執行 ANALYZE 時,系統會自動探索並統計所有邏輯分區,無需手動指定每個分區;

    • 僅在需要快速更新特定邏輯分區統計時,才使用 PARTITION 子句指定分區。

  2. 利用增量統計資訊更新

    • 當資料僅寫入少數邏輯分區時,可以僅對這些分區執行 ANALYZE;

    • 系統會自動觸發父表統計資訊合并,無需重新統計所有分區。

  3. 注意邏輯分區數量

    • 當邏輯分區數量過多(如數千個)時,首次 ANALYZE 可能耗時較長,建議在業務低峰期執行;

  4. 注意低版本的邏輯分區表 ANALYZE 效能問題

    • 在 Hologres V4.1.20 以下版本中,對邏輯分區表執行 ANALYZE 時,前台 ANALYZE 操作與後台 trigger load stats 任務之間存在 SUE 鎖競爭。由於 ANALYZE 邏輯分區表會持續產生統計資訊 binlog,後台 trigger load stats 會反覆訂閱並載入同一張表的統計資訊,導致鎖等待和重試,隨著子分區數量增加,ANALYZE 執行時間可能顯著延長(出現 10 秒層級的停頓)。

    • V4.2.5 及以上版本已對此進行最佳化,對同一張表、同一個 version 的 load stats 操作增加了去重處理,避免了重複載入統計資訊導致的鎖競爭問題。建議受此問題影響的使用者升級到 V4.2.5 及以上版本。

  5. 配合 AUTO ANALYZE 使用

    • 邏輯分區表同樣受 AUTO ANALYZE 管理,AUTO ANALYZE 會自動識別需要更新統計的邏輯分區。

ANALYZE 命令的可配置參數

參數

參數描述

支援版本

預設值

說明 / 使用樣本

hg_experimental_analyze_foreign_partitions_access_limit

ANALYZE 外表時,隨機採樣操作最多允許訪問的分區數量

v0.10及以上

0(不限)

-- 只採樣100個分區,防止隨機採樣時掃描外表資料量超限制

ALTER DATABASE dbname SET hg_experimental_analyze_foreign_partitions_access_limit = 100;

hg_analyze_foreign_table_max_sample_row_count

ANALYZE 外表時,隨機採樣操作最大採樣行數

v4.1及以上

0(不限),詳見版本動態。

AUTO ANALYZE 自動統計資訊收集

從 Hologres V0.10 起,Hologres支援自動統計資訊收集機制 AUTO ANALYZE

  • 根據建立表、資料寫入和變更情況自動判斷哪些表需要統計資訊更新;

  • 在後台非同步調度統計資訊收集任務,不需要使用者手動逐表 ANALYZE;

  • 降低漏做 ANALYZE 導致缺失統計資訊的風險。

開關與生效範圍

資料庫級開關

  • 配置參數為hg_enable_start_auto_analyze_worker,Hologres V0.10開始,即為預設開啟。

-- 查看當前資料庫是否開啟 AUTO ANALYZE
SHOW hg_enable_start_auto_analyze_worker;

-- 關閉(僅臨時排查、規避問題時使用)
ALTER DATABASE dbname SET hg_enable_start_auto_analyze_worker = OFF;

-- 重設回預設值ON(推薦)
ALTER DATABASE dbname RESET hg_enable_start_auto_analyze_worker;

說明:上述 GUC 為資料庫級配置,SESSION層級/ROLE層級配置均無效,必須通過 ALTER DATABASE 設定,才能對該 DB 生效,僅 superuser 可修改。

表級開關

Hologres 支援對單張表單獨控制 AUTO ANALYZE 行為。

行為說明

  • 關閉單表的 AUTO ANALYZE

ALTER TABLE my_table SET (autovacuum_enabled = false);
  • 開啟單表的 AUTO ANALYZE(恢複預設行為)

-- 推薦,重設以恢複預設
ALTER TABLE my_table RESET (autovacuum_enabled);

-- 或者顯式設定為 true(不推薦)
ALTER TABLE my_table SET (autovacuum_enabled = true);
  • 查看錶的 autovacuum_enabled 狀態

SELECT relname, reloptions FROM pg_class WHERE relname = 'my_table';

 relname  |         reloptions
----------+----------------------------
 my_table | {autovacuum_enabled=false}
(1 row)

典型使用情境

  1. 特殊業務表不需要統計資訊

    • 某些表僅用於臨時儲存或日誌記錄,不參與複雜查詢,無需收集統計資訊;

    • 資料量大且經常變化,又無需統計資訊的表,通過設定 autovacuum_enabled = false 可避免不必要的資源消耗。

  2. 統計資訊已通過手動維護

    • 對於某些關鍵表,您可能已經建立了定期手動 ANALYZE 的流程,滿足了業務需求。

  3. 臨時禁用以降低資源佔用

    • 在業務高峰期或緊急故障處理時,可臨時關閉部分表的 AUTO ANALYZE;

    • 待業務恢複後再重新開啟或手動執行 ANALYZE。

注意事項

  • 對於分區表:

    • 不建議對分區子表設定 autovacuum_enabled = false,否則可能導致該子表長期處於「無法合并」狀態,影響父表統計資訊的準確性;

    • 如需禁用,建議僅對分區父表設定。

  • 表級開關優先順序高於資料庫級開關:

    • 即使資料庫級 AUTO ANALYZE 開啟,設定了 autovacuum_enabled = false 的表仍不會被 AUTO ANALYZE 處理。

列級開關

Hologres 支援通過列級屬性控制是否對某列執行 ANALYZE 或 AUTO ANALYZE,適用於以下情境:

  • 超寬列(如超長 Text 等)統計開銷大,但對查詢計劃協助有限;

  • 某些列從不參與 Join、過濾或彙總,無需收集統計資訊;

  • 需要減少 AUTO ANALYZE 的資源消耗。

控制參數為以下column option:

  • enable_auto_analyze:僅控制該列是否參與自動 AUTO ANALYZE,預設為 true

  • 設定方式(通過 ALTER TABLE 命令):

-- 禁用某列的 AUTO ANALYZE,但仍允許手動 ANALYZE
ALTER TABLE t ALTER COLUMN large_text_col SET (enable_auto_analyze = false);

-- 恢複預設行為(重新啟用)
ALTER TABLE t ALTER COLUMN large_text_col RESET (enable_auto_analyze);
  • 注意事項:

    • 列層級設定 enable_auto_analyze = false 後,AUTO ANALYZE 任務不會再收集該列的統計資訊,但仍可通過手動 ANALYZE table_name;ANALYZE table_name(col); 顯式收集;

    • 如果某列對查詢計劃有重要影響(如 Join 列、過濾條件列),不建議禁用其統計資訊收集。

AUTO ANALYZE 的觸發邏輯

AUTO ANALYZE 綜合多類訊號,判斷是否需要對某個表執行統計資訊更新:

  1. 資料變更量

    • 僅針對Hologres普通表(不包括外表);

    • 1分鐘為周期,收集FE自身觀察到的表INSERT/UPDATE/DELETE操作的行數,如果變化超過閾值,則觸發一次 AUTO ANALYZE(快速響應);

    • 10分鐘為周期,從儲存引擎擷取各表的插入/更新/刪除等變化行數,超過閾值,則觸發一次 AUTO ANALYZE(精確校準);

  2. Schema 變更

    • 僅針對Hologres普通表(不包括外表);

    • 1分鐘為周期,收集發生如下變化的表,進行 AUTO ANALYZE:

      • ADD / DROP COLUMN;

      • 分區表(包括邏輯分區表)ATTACH / DETACH 子分區。

  3. 缺失統計資訊 / 無法合并分區父表統計資訊

    • 適用於Hologres普通表和外表;

    • 1分鐘為周期,收集缺失統計資訊的表/欄位,以及無法達到統計資訊增量合并條件的子分區。

  4. 外表

    • 僅適用於非 External Database 下,通過CREATE FOREIGN TABLEIMPORT FOREIGN SCHEMA引入或 Auto Load 機制自動引入的外表;

    • 當前僅支援對 MaxCompute 外表進行 AUTO ANALYZE;

    • 4小時為周期,定期檢查DB中所有外表,在兩次檢查之間,有無外部資料變更(有外部資料變更的標準是對應外表的 last_modify_timestamp 處於兩次檢查間隔之間),有則觸發一次 AUTO ANALYZE。

  5. 保底統計

    • 在淩晨 1:00-5:00 的視窗內,會對持續有變更但未觸發閾值(>5000行變化,<10%變化量)的表做一次「兜底」AUTO ANALYZE,捕捉欄位資料分布的漂移(例如,第二天0點後寫入的date類型欄位,和前一天完全不同,資料分布發生變化)。

  6. 訪問熱點表(僅用於External Database)

    • External Database 開啟enable_auto_analyze參數之後,Hologres系統將開始統計系統本次啟動以來,近期訪問過的表,將他們加入觀測列表;

    • 1小時為周期,將觀測列表中「近期頻繁訪問」的表,觸發一次 AUTO ANALYZE;

    • 要注意的是,系統重新啟動之後,訪問過的表將清除,並重新開始記錄。

External Database 的 AUTO ANALYZE

  • HologresV3.0版本開始支援外部資料庫(External Database)功能,建立 External Database 時,可以開啟 AUTO ANALYZE(預設為關閉,詳見版本動態):

-- 建立 External Database 時,開啟 AUTO ANALYZE
-- 參考文檔:https://www.alibabacloud.com/help/zh/hologres/developer-reference/create-external-database
CREATE EXTERNAL DATABASE <ext_database_name> WITH
  metastore_type 'maxcompute'
  mc_project 'project_name'
  enable_auto_analyze 'true';

-- 建立 External Database 之後,為其開啟 AUTO ANALYZE
ALTER EXTERNAL DATABASE dbname WITH enable_auto_analyze 'true';

功能限制:V3.2及以下,External Database 能支援AUTO ANALYZE的條件是,CREATE EXTERNAL DATABASE上配有Access KeyAccess Secret。不支援對SLRSTS形式配置的External DatabaseAUTO ANALYZE。V4.0及以上無限制。

  • External Database 上的 AUTO ANALYZE 支援的metastore_type範圍為:dlf,dlf-paimon,dlf-rest,maxcompute

  • External Database 上的 AUTO ANALYZE 支援的表格式包括:MaxCompute、Paimon、Iceberg

  • External Database 上的 AUTO ANALYZE,預設會採用 External Database 的 Owner 身份,採用Time-based One-Time Password (TOTP)的認證方式來執行ANALYZE任務。如果Owner無充足的表許可權,則系統無法成功執行 AUTO ANALYZE 任務。

  • External Database 中的一張外表,能被 AUTO ANALYZE,需要滿足:

    • External Database的資料庫配置hg_enable_start_auto_analyze_worker = on; (預設on)

    • External Database的屬性enable_auto_analyzetrue(預設不配置,為false,詳見版本動態)

    • External Database Owner 需要有資料湖Project(如有)和表的查詢許可權

    • 表在3天內被至少訪問過一次

      • External Database 下的 AUTO ANALYZE,只關注被訪問過至少一次的外表;

      • 系統重新啟動後,如果外表被訪問過至少一次,則 AUTO ANALYZE 系統會將其加入觀測列表,定期觸發這些表的 AUTO ANALYZE;

註:External Database 中未訪問過的外表,第一次訪問,會通過快速行數估算機制,擷取行數作為保底統計資訊(見下文"快速行數估算"章節),仍有一定的統計資訊保障。

AUTO ANALYZE 的資源限制

為了避免系統背景 AUTO ANALYZE 任務,給使用者前台任務造成影響,Hologres 為 AUTO ANALYZE 功能制定了如下資源限制:

  • AUTO ANALYZE 任務執行時,預設單worker限制的記憶體是4 GB,如表資料量過大,採樣可能超出記憶體而導致 AUTO ANALYZE 的採樣SQL失敗,從而僅能收集行數資訊,無法收集列分布資訊(MCV、Histogram、NDV等)。可調整auto_analyze_work_memory_mb改變其行為。執行個體規格越大,AUTO ANALYZE 可用記憶體限制越大。

  • 執行個體層級 AUTO ANALYZE 任務同時調度的並發,通常情況下不會超過4,極端情況下不超過6。

  • 同一個分區表下的子分區 AUTO ANALYZE 任務,同時調度的並發最多為3。

  • AUTO ANALYZE預設最大收集256的統計資訊,如表超過256列,取前256列(對於分區表,分區列是優先列,即使在256列之後,也會被收集)。可通過調整hg_experimental_auto_analyze_max_columns_count改變此值。

  • AUTO ANALYZE 任務的採樣子SQL,採用低優先順序的Background Pool來運行,並限制了Query執行層並發,這會導致 AUTO ANALYZE 任務執行時間相比手動 ANALYZE 更長,使用者無需重視。

  • AUTO ANALYZE 對於外表,只會收集分區列的列統計資訊(例如,MCV等),不會對分區列以外的列,進行採樣收集列統計資訊。

AUTO ANALYZE 的可配置參數

Hologres AUTO ANALYZE 功能預設情況下無需修改任何參數。

在極少數業務情境下(例如資料寫入更新不頻繁情境、查詢負載不需要統計資訊、系統出現了 AUTO ANALYZE 引發的負載升高等問題),使用者可以通過修改部分預設參數來調整AUTO ANALYZE的行為,實現行為幹預,或達到部分效能調優的目的。

說明:只有superuser能調整 AUTO ANALYZE 的預設行為,且都需要DB層級設定參數,且在下一分鐘後生效。

-- Superuser,DB層級修改 AUTO ANALYZE 參數的預設值
ALTER DATABASE dbname SET <GUC> = <values>;

參數

參數描述

支援版本

預設值

說明 / 使用樣本

hg_enable_start_auto_analyze_worker

開啟 AUTO ANALYZE 功能

v0.10及以上

on

-- 臨時關閉DBAUTO ANALYZE功能ALTER DATABASE dbname SET hg_enable_start_auto_analyze_worker = off;

hg_experimental_auto_analyze_max_columns_count

AUTO ANALYZE 自動收集統計資訊的列數

v1.1.0及以上

256

ALTER DATABASE dbname SET hg_experimental_auto_analyze_max_columns_count =300;

auto_analyze_work_memory_mb

AUTO ANALYZE 單個表的記憶體限制,單位是MB

v1.1.54及以上

4096

-- 修改為9GBALTER DATABASE dbname SET auto_analyze_work_memory_mb = 9216;預設單個worker 4 GB,執行個體規格越大,Worker越多,真實記憶體限制越大)

auto_analyze_work_statement_timeout

AUTO ANALYZE 任務執行的逾時時間,單位是ms

V2.0及以上

3600000

-- 修改為3hALTER DATABASE dbname SET auto_analyze_work_statement_timeout = '3h';

hg_experimental_auto_analyze_max_foreign_table_partitions

AUTO ANALYZE 過程中,最多訪問的外表分區個數

v1.1.54及以上

100

如果外表分區數超過100,預設採用一級分區值字典序最大的100個分區的行數,來預估外表總體行數和分區列MCV。

hg_auto_analyze_run_with_serverless_computing

AUTO ANALYZE 是否採用 Serverless 資源運行

v3.1及以上

off(Serverless型執行個體預設為on)

一般無需調整,AUTO ANALYZE 通常消耗資源不多,且利用低優先順序進程後台運行,對執行個體負載影響小。

hg_auto_analyze_serverless_computing_query_priority

Serverless 任務優先順序,範圍 1~5,數值越大優先順序越高。註:需要先開啟hg_auto_analyze_run_with_serverless_computing

v3.1及以上

2

-- 修改為最高優先順序ALTER DATABASE dbname SET hg_auto_analyze_serverless_computing_query_priority = 5;

快速行數估算(Fast Num of Rows)

Hologres V3.1開始,Hologres 新增快速行數估算功能。當發現執行查詢的SQL中有表缺乏統計資訊,或者統計資訊可能到期時,Hologres 可以通過底層儲存或外部系統的元資訊快速估算錶行數,從而產生更合理的執行計畫。

Hologres V3.2開始,快速行數估算(Fast Num of Rows)功能預設開啟。

開關

開啟快速行數估算的方式:

-- 關閉(僅適用於臨時處置,或全庫明確不需要統計資訊的情況)
ALTER DATABASE dbname SET hg_experimental_get_fast_num_of_rows = OFF;

-- V3.2及以上,開啟(重設回預設值)
ALTER DATABASE dbname RESET hg_experimental_get_fast_num_of_rows;

-- V3.1及以下,開啟
ALTER DATABASE dbname SET hg_experimental_get_fast_num_of_rows = ON;

注意:快速行數估算不能替代完整的統計資訊收集,仍然建議在關鍵業務表上通過 ANALYZE/AUTO ANALYZE 保持統計資訊新鮮。

使用限制

  • 快速行數估算適用於普通表(包括分區表)、External Database中的外表等情況。

  • 快速行數估算功能,估算出的行數不保證完全準確。例如,為效能起見,在Hologres分區表上,最多隻會使用60個分區(預設)的行數統計去估算分區表總體行數。

  • V4.1.15及以下,快速行數估算對外表類型(Foreign Table)預設不開啟,可通過參數hg_experimental_enable_foreign_table_get_fast_num_of_rows開啟。V4.1.16及以上預設開啟。

  • 對於外表類型,快速行數估算擷取僅支援MaxCompute外表,Paimon外表和Iceberg外表。

樣本

  1. hg_experimental_get_fast_num_of_rows樣本

若表沒有統計資訊,開啟快速行數估算後,可得到更準確的行數。(Hologres V3.2及以上預設開啟)

-- V3.2+
create table test_tbl (a int);
insert into test_tbl select * from generate_series (1, 999);

-- 準確的行數估計(rows=999)
explain select count(1) from test_tbl ;
                                       QUERY PLAN
----------------------------------------------------------------------------------------
 Final Aggregate  (cost=0.00..5.00 rows=1 width=8)
   ->  Gather  (cost=0.00..5.00 rows=10 width=8)
         ->  Partial Aggregate  (cost=0.00..5.00 rows=10 width=8)
               ->  Local Gather  (cost=0.00..5.00 rows=20 width=8)
                     ->  Partial Aggregate  (cost=0.00..5.00 rows=20 width=8)
                           ->  Seq Scan on test_tbl  (cost=0.00..5.00 rows=999 width=1)

下面是一個線上的真實案例:

未開啟此功能時,若表沒有統計資訊,查詢計劃中Scan節點會有rows=1000行(表示沒有統計資訊,根據預設1000行預估產生計劃)

當開啟該功能後,若表沒有統計資訊,查詢計劃Scan節點rows不等於1000行(系統調用了底層儲存引擎的元資訊,擷取了表的行數)。

快速行數估算的可配置參數

參數

參數描述

支援版本

預設值

說明 / 使用樣本

hg_experimental_get_fast_num_of_rows

是否開啟快速行數算。

v3.1及以上

off(V3.1)on(V3.2+)

hg_experimental_enable_foreign_table_get_fast_num_of_rows

是否開啟外錶行數估算。

v3.1及以上

off(V4.1.15及以下)on(V4.1.16+)

-- 開啟方式ALTER DATABASE dbname SET hg_experimental_enable_foreign_table_get_fast_num_of_rows = on;

hg_experimental_fast_num_rows_foreign_partitions_access_limit

對於外表分區表,最多擷取多少個分區的行數,作為整體估算的依據。註:需開啟外錶行數估算才生效。

v3.1及以上

60

這是為了控制快速行數估算的時間開銷。

hg_get_fast_num_of_rows_holo_partitions_access_limit

對於Hologres物理分區表,最多擷取多少個分區的行數,作為整體估算的依據。

v3.1及以上

60

這是為了控制快速行數估算的時間開銷。

查看 ANALYZE 與 AUTO ANALYZE 的歷史執行記錄

ANALYZE 與 AUTO ANALYZE 在執行之後,其執行記錄會被寫入 Query Log,使用者可以通過 hologres.hg_query_log 視圖查看 ANALYZE 與 AUTO ANALYZE 的歷史執行情況,包括執行的 SQL、耗時、狀態等資訊。

如何識別 ANALYZE 與 AUTO ANALYZE 的 Query Log 記錄

ANALYZE 和 AUTO ANALYZE ,及其發出的採樣SQL,會被單獨記錄在 Query Log 中。

執行記錄在 Query Log 中具有以下特徵:

欄位

ANALYZE

AUTO ANALYZE

說明

usename

執行ANALYZE的使用者名稱

system

AUTO ANALYZE 使用系統內部賬戶執行,在 Query Log 中統一顯示為 system

application_name

執行ANALYZEsessionapplication name

AutoAnalyze

AUTO ANALYZE 架構串連使用 AutoAnalyze作為application_name

採樣子 SQL 的 application_name

Hologres SQL Generated BY ANALYZE

Hologres SQL Generated BY AUTO ANALYZE

command_tag

ANALYZE

ANALYZE

所執行的命令類型

採樣子 SQL 的 command_tag

SELECT

SELECT

採樣子SQLSELECT語句,可通過此語句查看採樣的資源消耗。

ANALYZE 及其發出的採樣SQL,通過query欄位的注釋,或者extended_info->>'source_query_id'關聯。

SELECT query_id,
       extended_info->>'src_query_id' as "source query id",
       application_name,
       status,
       duration
FROM   hologres.hg_query_log
WHERE  query_start >= now() - interval '1 hour'
  AND  application_name IN ('AutoAnalyze', 'Hologres SQL Generated BY AUTO ANALYZE')
ORDER BY query_start DESC
LIMIT  2;
      query_id       |   source query id   |            application_name            | status  | duration
---------------------+---------------------+----------------------------------------+---------+----------
 1004019226350863009 | 1004019226350778807 | Hologres SQL Generated BY AUTO ANALYZE | SUCCESS |      119
 1004019226350778807 |                     | AutoAnalyze                            | SUCCESS |     3276

查詢樣本

  • 查看最近的 AUTO ANALYZE 執行記錄

SELECT usename,
       status,
       duration,
       query_start,
       query_end,
       query,
       application_name
FROM   hologres.hg_query_log
WHERE  query_start >= now() - interval '1 hour'
  AND  application_name IN ('AutoAnalyze')
ORDER BY query_start DESC
LIMIT  20;

       query_id,
       extended_info->>'src_query_id' as "source query id"
  • 查看某張表的 AUTO ANALYZE 執行歷史

SELECT status,
       duration,
       query_start,
       query
FROM   hologres.hg_query_log
WHERE  query_start >= now() - interval '1 day'
  AND  application_name IN ('AutoAnalyze')
  AND  query LIKE '%my_table_name%'
ORDER BY query_start DESC;
  • 統計近3天 AUTO ANALYZE 的執行概況

SELECT query_date,
       status,
       COUNT(*)          AS task_count,
       AVG(duration)     AS avg_duration_ms,
       MAX(duration)     AS max_duration_ms
FROM   hologres.hg_query_log
WHERE  query_start >= CURRENT_DATE::timestamptz - interval '2 day'
  AND  application_name IN ('AutoAnalyze')
  AND  command_tag = 'ANALYZE'
  AND  (status = 'SUCCESS' OR (
            message NOT LIKE '%does not exist%'
        AND message NOT LIKE '%retry later%'))
GROUP BY query_date, status
ORDER BY query_date DESC;
  • 查看近1天失敗的 AUTO ANALYZE 任務

SELECT query_start,
       duration,
       message,
       query
FROM   hologres.hg_query_log
WHERE  query_start >= now() - interval '1 day'
  AND  application_name IN ('AutoAnalyze', 'Hologres SQL Generated BY AUTO ANALYZE')
  AND  status != 'SUCCESS'
  AND  (message NOT LIKE '%does not exist%'
        AND message NOT LIKE '%retry later%')
ORDER BY query_start DESC;

注意事項

  • 由於 AUTO ANALYZE 串連以內部管理員身份發起,普通使用者需具備 pg_read_all_stats 角色或資料庫管理員許可權才能查看完整的 AUTO ANALYZE 執行記錄;

  • 若發現 Query Log 中長時間沒有 AUTO ANALYZE 記錄,建議檢查 AUTO ANALYZE 開關是否已開啟。

查看與排查統計資訊

查看錶的統計資訊(hologres_statistic.hg_table_statistic)

表的統計資訊被儲存在hologres_statistic.hg_table_statistic表中,同時在系統資料表中可以觀測到。

  1. 查詢該表擷取最近一次analyze的統計資訊。

SELECT schema_name,                -- 表的schema
       table_name,                 -- 表名
       user_name,                  -- 最近一次ANALYZE的使用者
       schema_version,             -- 最近一次ANALYZE的表Schema版本
       total_rows,                 -- 最近一次ANALYZE的行數
       sample_rows,                -- 最近一次ANALYZE擷取統計資訊的採樣行數
       analyze_timestamp,          -- 最近一次ANALYZE的結束時間
       analyze_count               -- 到當前為止總計的ANALYZE次數
FROM   hologres_statistic.hg_table_statistic
WHERE  unique_name = hologres.hg_internal_statistic_unique_name ('schemaname', 'tablename')
ORDER BY analyze_timestamp DESC;

-- 樣本輸出
 schema_name | table_name |    user_name     | schema_version | total_rows | sample_rows |  analyze_timestamp  | analyze_count
-------------+------------+------------------+----------------+------------+-------------+---------------------+---------------
 public      | test_fnr   |   BASIC$test_fnr |             -1 |        999 |         999 | 2026-03-02 22:05:29 |             2
(1 row)

V3.1以下,

  • 每個表在hologres_statistic.hg_table_statistic表中有0~n條記錄。0條表示從未進行過ANALYZE,1條及以上表示運行過analyze。

  • 若出現兩條及以上的情況,兩條記錄的schema_version一定不一樣,因為表的schema變化了(例如,ADD COLUMN,CALL SET_TABLE_PROPERTY等)會產生新的版本,會增加一條統計資訊記錄,老的schema_version對應的記錄不再被使用。

  • 樣本查詢結果如下,同一個表有2條記錄,而第二條記錄的schema_version低於第一條,那麼第二條將作廢,不會被使用,也無需關注。Hologres暫不會清理hg_table_statistic表中的歷史到期記錄,同時使用者無需關心老的資料。

 schema_name | table_name |    user_name     | schema_version | total_rows | sample_rows |  analyze_timestamp  | analyze_count
-------------+------------+------------------+----------------+------------+-------------+---------------------+---------------
 public      | test_fnr   |   BASIC$test_fnr |             13 |        999 |         999 | 2026-03-01 18:05:29 |             2
 public      | test_fnr   |   BASIC$test_fnr |             12 |        999 |         999 | 2026-03-01 08:05:29 |             1
(1 row)

V3.1及以上,

  • 每個表在hologres_statistic.hg_table_statistic表中有0~1條記錄,0條表示從未進行過ANALYZE,1條表示運行過analyze。

  • schema_version統一為-1(代表Deprecated)。

  • 這意味著,很多DDL操作,都不再會使統計資訊失效。例如CALL SET_TABLE_PROPERTY等,不會重新觸發AUTO ANALYZE,繼續沿用統計資訊即可。相比Hologres V3.0及以前,大幅減少了AUTO ANALYZE的觸發頻率。

  1. 查詢行數等統計資訊

行數資訊記錄在pg_class表的reltuples欄位。

-- relallvisible > 0:表有行數統計資訊
-- relallvisible = 0:錶行數未知,此時不能參考reltuples
-- relallvisible < 0:表無統計資訊
SELECT relallvisible, reltuples FROM pg_class WHERE relname = 'test_table';

如果表沒有統計資訊,可參看下文"查看缺失統計資訊的表"一節,找出缺失的原因。

  1. 查詢列統計資訊

通過查詢pg_stats視圖,可擷取當前表的所有列的統計資訊。例如,擷取test_tableds列統計資訊:

select * from pg_stats where tablename = 'test_table' and attname = 'ds';

 schemaname | tablename  | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram
------------+------------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+----------------------
 public     | test_table | ds      | f         |         0 |         4 |          1 | {20241104}       | {1}               |                  |             |                   |                        |
(1 row)

如果列沒有統計資訊,可參看下文"查看缺失統計資訊的表"一節,找出缺失的原因。

查看缺失統計資訊的表

Hologres 提供視圖 HG_STATS_MISSING(視圖名稱以實際版本為準),用於查看當前 DB 中缺失統計資訊的表,便於排查需要補充 ANALYZE 的對象。

具體欄位與使用方式請參考對應執行個體文檔或控制台協助。

常見異常與排查建議

  1. 統計資訊hologres_statistic.hg_table_statistic表中,查出0條的可能原因:

  • 從未執行過 ANALYZE(手動或 AUTO ANALYZE);

  • AUTO ANALYZE 未工作,或該表未滿足觸發條件;

建議操作:

  • 先手動執行:

ANALYZE schema_name.table_name;
  • 若仍長期無法由 AUTO ANALYZE 覆蓋,建議檢查 AUTO ANALYZE 開關、GUC 配置,或聯絡支援人員。

  1. analyze_timestamp 明顯過舊可能原因:

  • AUTO ANALYZE 被關閉或限制(如 autovacuum_enabled = false);

  • AUTO ANALYZE 資源不足或失敗(可結合日誌/監控排查);

建議操作:

  • 手動 ANALYZE 一次後觀察效果;

  • 檢查:

    • hg_enable_start_auto_analyze_worker 是否開啟;

    • 是否誤設定了 autovacuum_enabled = false 或相關 GUC 限制過嚴;

    • 查看 Query Log 中是否有 AUTO ANALYZE 相關任務的報錯。

  1. 查詢計劃中行數估計異常(明顯偏小或偏大)

  • 檢查對應表是否缺失統計或統計過舊;

  • 檢查謂詞列是否有統計資訊(pg_stats),對關鍵列執行列級 ANALYZE;

  • 是否關閉或未啟用快速行數估算功能。

  1. 分區表父子統計資訊不一致或父表缺失統計資訊

  • 現象:分區父表在 hologres_statistic.hg_table_statistic 中沒有記錄,或 total_rows 明顯小於所有子錶行數之和,或父表的分區列統計資訊MCV分布落後(比如pg_statsds列缺少昨日的分布);

  • 排查要點:

    • 檢查增量式分區 ANALYZE / AUTO ANALYZE是否被關閉;

SHOW hg_experimental_enable_incremental_analyze;
SHOW hg_experimental_enable_incremental_auto_analyze;
  • 使用 HG_STATS_MISSING視圖查看是否存在無法合并的子表;

  • 查看 Query Log 中是否有 AUTO ANALYZE 相關任務的報錯;

  • 對缺失統計資訊的子表手動執行 ANALYZE child_table; 或在業務低峰期對父表執行一次 ANALYZE partition_parent_table;,讓系統補齊併合並統計資訊。

  1. 某些列在 pg_stats 中沒有統計資訊

  • 現象:表存在該列,但pg_stats視圖中看不到對應列的統計資訊。

  • 排查要點:

    • 檢查是否通過列屬性禁用了統計(enable_analyze = falseenable_auto_analyze = false);

SELECT attoptions
  FROM pg_attribute
 WHERE attrelid = 'tablename'::regclass::oid
   AND attname = 'columnname';
-[ RECORD 1 ]----------------------
attoptions | {enable_analyze=false}
  • 確認該列是否參與過 ANALYZE(手動或 AUTO ANALYZE),必要時執行列級 ANALYZE table_name(col_name);

SELECT query_id,
       application_name,
       status,
       query_start,
       query
FROM   hologres.hg_query_log
WHERE  query_start >= now() - interval '1 hour'
  AND  application_name IN ('Hologres SQL Generated BY ANALYZE', 'Hologres SQL Generated BY AUTO ANALYZE')
  AND  query like '%tablename%'
ORDER BY query_start DESC
LIMIT  2;
  • 是否為特殊列類型(byteajsonb)。

  • 如果表執行了AUTO ANALYZE,但是所有列都沒有統計資訊,則考慮是否AUTO ANALYZE任務執行異常。例如AUTO ANALYZE是否執行逾時,因auto_analyze_work_statement_timeout預設為1h,如果hologres.hg_query_log 中的AUTO ANALYZE任務,執行了duration >= 3600000,這種情況下,只會採集行數資訊,而不會有列統計資訊。

  1. AUTO ANALYZE 已執行但查詢計劃未明顯改善

  • 現象:從 hologres.hg_query_log 中能看到針對某表的 AUTO ANALYZE 記錄,但實際查詢計劃仍然使用明顯不合理的行數估計或 Join 順序;

  • 排查要點:

    • AUTO ANALYZE是否執行逾時,因auto_analyze_work_statement_timeout預設為1h,如果hologres.hg_query_log 中的AUTO ANALYZE任務,執行duration >= 3600s,這種情況下,只會採集行數資訊,而不會有列統計資訊。

    • 檢查是否存在 Hint、固定 Join 順序、遺留的會話級 GUC(如 enable_nestloop 等)幹擾了最佳化器選擇;

    • 對關鍵表/列執行一次手動 ANALYZE 後重跑查詢,若仍無改善,建議結合 Query Log、FE 日誌或上報支援人員進一步排查。

  1. 統計資訊導致的 OOM / 記憶體超限問題

  • 現象:複雜多表 Join 報錯 Query executor exceeded total memory limitation ...,或計劃選擇了極端不合理的 Join 策略(如大表驅動大表的 Nested Loop 等);

  • 排查要點:

    • 確認相關表是否缺失統計或統計嚴重過舊(結合hg_table_statistic中的記錄和 AUTO ANALYZE 執行記錄);

    • 對 Join 列、過濾列執行列級 ANALYZE,必要時提高採樣精度或開啟快速行數估算能力;

    • 若問題只在某些極端資料分布或峰值情境出現,可與支援人員評估是否需要調整統計模型或相關 GUC(如 AUTO ANALYZE 閾值、記憶體上限等)。

Serverless 運行 ANALYZE 與 AUTO ANALYZE

Hologres V3.1開始,在使用 Serverless 型執行個體或已開通 Serverless 計算資源的執行個體中,ANALYZE 和 AUTO ANALYZE 支援運行在 Serverless 資源上,減輕對本執行個體的 CPU / 記憶體壓力。

本節結合相關 GUC,說明在 Serverless Computing 情境下,手動 ANALYZE 與 AUTO ANALYZE 的典型行為與推薦配置。

手動 ANALYZE 與 Serverless Computing

  • hg_serverless_computing_enable_analyze_statement

    • 描述:控制手動 ANALYZE 語句是否支援通過 Serverless 任務執行;

    • 行為:

      • on(預設)時,系統允許將 ANALYZE 語句下推到 Serverless 計算資源執行,統計任務對執行個體本身的影響更小;

      • off 時,ANALYZE 在本執行個體資源上執行。

    • 典型建議:

      • 在 Serverless 型執行個體中,預設為on,只允許利用 Serverless 資源完成統計任務;

      • 如需排查問題或對資源使用有特殊要求時,可臨時設定為 off,讓 ANALYZE 明確在本地資源上運行。

AUTO ANALYZE 與 Serverless Computing

系統會在產生 AUTO ANALYZE 任務時,根據以下 GUC 決定是否使用 Serverless 資源,以及如何控制 Serverless 任務行為:

  • hg_auto_analyze_run_with_serverless_computing

    • 描述:是否通過 Serverless 計算資源執行 AUTO ANALYZE 任務。普通執行個體預設off,Serverless型執行個體預設on

    • 行為:

      • on 時,AUTO ANALYZE 任務會將採樣計算髮送到 Serverless 資源集區;

      • off 時,AUTO ANALYZE 繼續通過本執行個體資源完成統計。

-- DB層級設定
ALTER DATABASE datname SET hg_auto_analyze_run_with_serverless_computing = on;
  • hg_auto_analyze_serverless_computing_query_priority

    • 描述:Serverless AUTO ANALYZE 任務的優先順序,範圍為 1~5,值越大優先順序越高,預設 2

    • 行為:

      • 當開啟 Serverless AUTO ANALYZE 時,系統會通過 SET hg_experimental_serverless_tasks_query_priority = <value>; 為每條統計任務設定對應優先順序;

      • 適用於與其他 Serverless 任務(如 ETL、離線查詢)共用資源集區時,控制統計任務在整體隊列中的搶佔能力;

    • 建議:

      • 生產環境中通常保持在中等優先順序(如預設 2 或適當調大到 3),避免與核心業務作業爭搶過多資源;

      • 對統計資訊及時性要求極高、且 Serverless 資源充足的情境,可適當提高優先順序。

  • hg_auto_analyze_serverless_computing_enable_persisted_snapshot

    • 描述:是否在 Serverless AUTO ANALYZE 任務中採用持久化快照(persisted snapshot),即通過 SET hg_experimental_enable_persisted_snapshot = on/off; 控制是否跳過額外的 flush;

    • 非 Serverless 型執行個體預設off,Serverless 型執行個體預設on

    • 行為:

      • on 時,統計任務會盡量複用持久化快照,減少觸發一次 flush,更適合高頻統計或大量分區表情境;

      • off 時,統計任務盡量採用更新的snapshot,適合對一致性或特定版本隔離有更高要求的情境。

    • 建議:

      • 沒有必要不作調整。

Serverless Computing 情境下的使用建議

  1. 優先利用 Serverless Computing 承載重型 ANALYZE 任務

    • 在 ANALYZE 資料量超大的表或外表時,建議開啟:

      • 手動 ANALYZE:set hg_computing_resource = 'serverless'; ANALYZE my_table;

      • AUTO ANALYZE:ALTER DATABASE mydb SET hg_auto_analyze_run_with_serverless_computing = on;

    • 這樣可以將統計計算壓力遷移到 Serverless 資源集區,降低對執行個體線上查詢的幹擾。

  2. 根據業務重要性設定 Serverless AUTO ANALYZE 任務優先順序

    • 在 Serverless 型執行個體中,對統計時效敏感、依賴最新統計資訊的關鍵業務庫,可適當提高 hg_auto_analyze_serverless_computing_query_priority

    • 在普通執行個體中,通常仍使用本地資源做 AUTO ANALYZE 即可。

  3. 調參前同樣遵循"小步試探"原則

    • Serverless Computing 相關 GUC 同樣屬於進階參數,調整前建議先在測試或預發環境驗證:

      • 觀察統計任務在 Serverless 資源集區中的排隊與執行時間長度;

      • 關注對核心業務查詢的延遲與資源佔用影響;

    • 確認無明顯副作用後,再在生產環境分庫或分階段推廣。