本文档介绍Hologres中ANALYZE命令,以及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、Snapshot和Tag单独ANALYZE
典型用法
典型推荐用法
对 Join 列、Group By 列、过滤条件列执行列级 ANALYZE:
ANALYZE tablename (order_id, user_id, dt);ANALYZE tablename;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);分区表与增量式分区 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统计收集,再统一合并出父表的统计信息:
统计信息变化的子表(stats-changed partitions)
子表数据自上次
ANALYZE以来发生了显著变化(插入、更新、删除);判断依据:
数据变更行数达到变更阈值(
1% * 上次的表行数)。
无法合并统计信息的子表(unable-to-merge partitions)
子表缺失完整的统计信息,导致无法参与父表统计信息合并;
常见原因包括:
从未执行过 ANALYZE:子表统计信息完全缺失;
列统计信息缺失:指定列缺少必要的统计信息(如 MCV、Histogram、NDV的HLL 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 时,系统采用与物理分区表类似但独立的处理逻辑:
自动发现逻辑分区
对逻辑分区(父)表执行
ANALYZE logical_partitioned_table;时,系统会自动从存储引擎查询该表的所有逻辑分区;
自适应筛选需要统计的逻辑分区
与物理分区表类似,系统会识别以下逻辑分区并优先对其进行统计:
统计信息变化的子表(stats-changed partitions)
子表数据自上次
ANALYZE以来发生了显著变化(插入、更新、删除),判断依据同前述物理分区表;缺失统计信息的逻辑分区:从未执行过 ANALYZE,或指定列缺少必要统计信息(如 HLL 计数器);
统计信息不可用的逻辑分区:列统计信息与当前列类型不匹配,或统计信息过时。
跳过空分区:行数为 0 的逻辑分区会被自动忽略。
系统输出提示信息,例如:
INFO: will analyze 10 logical partitions first逐分区采样与统计收集
对每个需要统计的逻辑分区,系统构造带有分区列过滤条件的采样查询(如
WHERE user_id = 1 AND event_date = '2024-11-04');在该逻辑分区范围内进行数据采样,收集列级统计信息(NDV、MCV、Histogram、HLL 计数器等);
统计信息以逻辑分区为粒度存储在
hologres_statistic.hg_table_statistic中,通过unique_name字段区分不同逻辑分区。
合并父表统计信息
当所有逻辑分区的统计信息收集完成后,系统自动触发统计信息合并,生成父表统计信息。
执行示例与输出
示例 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 最佳实践
优先对逻辑分区父表执行 ANALYZE
对逻辑分区父表执行
ANALYZE时,系统会自动发现并统计所有逻辑分区,无需手动指定每个分区;仅在需要快速更新特定逻辑分区统计时,才使用
PARTITION子句指定分区。
利用增量统计信息更新
当数据仅写入少数逻辑分区时,可以仅对这些分区执行 ANALYZE;
系统会自动触发父表统计信息合并,无需重新统计所有分区。
注意逻辑分区数量
当逻辑分区数量过多(如数千个)时,首次 ANALYZE 可能耗时较长,建议在业务低峰期执行;
配合 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)典型使用场景
特殊业务表不需要统计信息
某些表仅用于临时存储或日志记录,不参与复杂查询,无需收集统计信息;
数据量大且经常变化,又无需统计信息的表,通过设置
autovacuum_enabled = false可避免不必要的资源消耗。
统计信息已通过手动维护
对于某些关键表,您可能已经建立了定期手动 ANALYZE 的流程,满足了业务需求。
临时禁用以降低资源占用
在业务高峰期或紧急故障处理时,可临时关闭部分表的 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 综合多类信号,判断是否需要对某个表执行统计信息更新:
数据变更量
仅针对Hologres普通表(不包括外表);
1分钟为周期,收集FE自身观察到的表
INSERT/UPDATE/DELETE操作的行数,如果变化超过阈值,则触发一次 AUTO ANALYZE(快速响应);10分钟为周期,从存储引擎获取各表的插入/更新/删除等变化行数,超过阈值,则触发一次 AUTO ANALYZE(精确校准);
Schema 变更
仅针对Hologres普通表(不包括外表);
1分钟为周期,收集发生如下变化的表,进行 AUTO ANALYZE:
ADD / DROP COLUMN;
分区表(包括逻辑分区表)ATTACH / DETACH 子分区。
缺失统计信息 / 无法合并分区父表统计信息
适用于Hologres普通表和外表;
1分钟为周期,收集缺失统计信息的表/字段,以及无法达到统计信息增量合并条件的子分区。
外表
仅适用于非 External Database 下,通过
CREATE FOREIGN TABLE或IMPORT FOREIGN SCHEMA引入或 Auto Load 机制自动引入的外表;当前仅支持对 MaxCompute 外表进行 AUTO ANALYZE;
4小时为周期,定期检查DB中所有外表,在两次检查之间,有无外部数据变更(有外部数据变更的标准是对应外表的 last_modify_timestamp 处于两次检查间隔之间),有则触发一次 AUTO ANALYZE。
保底统计
在凌晨 1:00-5:00 的窗口内,会对持续有变更但未触发阈值(>5000行变化,<10%变化量)的表做一次「兜底」AUTO ANALYZE,捕捉字段数据分布的漂移(例如,第二天0点后写入的date类型字段,和前一天完全不同,数据分布发生变化)。
访问热点表(仅用于External Database)
External Database 打开
enable_auto_analyze参数之后,Hologres系统将开始统计系统本次启动以来,近期访问过的表,将他们加入观测列表;1小时为周期,将观测列表中「近期频繁访问」的表,触发一次 AUTO ANALYZE;
要注意的是,系统重新启动之后,访问过的表将清除,并重新开始记录。
External Database 的 AUTO ANALYZE
Hologres从V3.0版本开始支持外部数据库(External Database)功能,创建 External Database 时,可以开启 AUTO ANALYZE(默认为关闭,详见版本动态):
-- 创建 External Database 时,开启 AUTO ANALYZE
-- 参考文档:https://help.aliyun.com/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 Key和Access Secret。不支持对SLR或STS形式配置的External Database做AUTO 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_analyze为true(默认不配置,为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 | -- 临时关闭DB的AUTO ANALYZE功能 |
hg_experimental_auto_analyze_max_columns_count | AUTO ANALYZE 自动收集统计信息的列数 | v1.1.0及以上 | 256 |
|
auto_analyze_work_memory_mb | AUTO ANALYZE 单个表的内存限制,单位是MB | v1.1.54及以上 | 4096 | -- 修改为9GB |
auto_analyze_work_statement_timeout | AUTO ANALYZE 任务执行的超时时间,单位是ms | V2.0及以上 | 3600000 | -- 修改为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 | -- 修改为最高优先级 |
快速行数估算(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外表。
示例
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 | 说明 |
| 执行ANALYZE的用户名 |
| AUTO ANALYZE 使用系统内部账户执行,在 Query Log 中统一显示为 |
| 执行ANALYZE的session的application name |
| AUTO ANALYZE 框架连接使用 |
采样子 SQL 的 |
|
| |
|
|
| 所执行的命令类型 |
采样子 SQL 的 |
|
| 采样子SQL为SELECT语句,可通过此语句查看采样的资源消耗。 |
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表中,同时在系统表中可以观测到。
查询该表获取最近一次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的触发频率。
查询行数等统计信息
行数信息记录在pg_class表的reltuples字段。
-- relallvisible > 0:表有行数统计信息
-- relallvisible = 0:表行数未知,此时不能参考reltuples
-- relallvisible < 0:表无统计信息
SELECT relallvisible, reltuples FROM pg_class WHERE relname = 'test_table';如果表没有统计信息,可参看下文"查看缺失统计信息的表"一节,找出缺失的原因。
查询列统计信息
通过查询pg_stats视图,可获取当前表的所有列的统计信息。例如,获取test_table的ds列统计信息:
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 的对象。
具体字段与使用方式请参考对应实例文档或控制台帮助。
常见异常与排查建议
统计信息hologres_statistic.hg_table_statistic表中,查出0条的可能原因:
从未执行过 ANALYZE(手动或 AUTO ANALYZE);
AUTO ANALYZE 未工作,或该表未满足触发条件;
建议操作:
先手动执行:
ANALYZE schema_name.table_name;若仍长期无法由 AUTO ANALYZE 覆盖,建议检查 AUTO ANALYZE 开关、GUC 配置,或联系技术支持。
analyze_timestamp 明显过旧可能原因:
AUTO ANALYZE 被关闭或限制(如
autovacuum_enabled = false);AUTO ANALYZE 资源不足或失败(可结合日志/监控排查);
建议操作:
手动 ANALYZE 一次后观察效果;
检查:
hg_enable_start_auto_analyze_worker是否开启;是否误设置了
autovacuum_enabled = false或相关 GUC 限制过严;查看 Query Log 中是否有 AUTO ANALYZE 相关任务的报错。
查询计划中行数估计异常(明显偏小或偏大)
检查对应表是否缺失统计或统计过旧;
检查谓词列是否有统计信息(pg_stats),对关键列执行列级 ANALYZE;
是否关闭或未启用快速行数估算功能。
分区表父子统计信息不一致或父表缺失统计信息
现象:分区父表在
hologres_statistic.hg_table_statistic中没有记录,或total_rows明显小于所有子表行数之和,或父表的分区列统计信息MCV分布落后(比如pg_stats中ds列缺少昨日的分布);排查要点:
检查增量式分区 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;,让系统补齐并合并统计信息。
某些列在 pg_stats 中没有统计信息
现象:表存在该列,但
pg_stats视图中看不到对应列的统计信息。排查要点:
检查是否通过列属性禁用了统计(
enable_analyze = false或enable_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;是否为特殊列类型(
bytea、jsonb)。如果表执行了AUTO ANALYZE,但是所有列都没有统计信息,则考虑是否AUTO ANALYZE任务执行异常。例如AUTO ANALYZE是否执行超时,因auto_analyze_work_statement_timeout默认为1h,如果
hologres.hg_query_log中的AUTO ANALYZE任务,执行了duration >= 3600000,这种情况下,只会采集行数信息,而不会有列统计信息。
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 日志或上报技术支持进一步排查。
统计信息导致的 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 场景下的使用建议
优先利用 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 资源池,降低对实例在线查询的干扰。
根据业务重要性设置 Serverless AUTO ANALYZE 任务优先级
在 Serverless 型实例中,对统计时效敏感、依赖最新统计信息的关键业务库,可适当提高
hg_auto_analyze_serverless_computing_query_priority;在普通实例中,通常仍使用本地资源做 AUTO ANALYZE 即可。
调参前同样遵循"小步试探"原则
Serverless Computing 相关 GUC 同样属于高级参数,调整前建议先在测试或预发环境验证:
观察统计任务在 Serverless 资源池中的排队与执行时长;
关注对核心业务查询的延迟与资源占用影响;
确认无明显副作用后,再在生产环境分库或分阶段推广。