更新时间:2025-07-08 GMT+08:00
分享

ANALYZE | ANALYSE

功能描述

用于收集有关数据库中表内容的统计信息,统计信息分为表级和列级。其中,表级统计信息存储在PG_CLASS中,列级统计结果存储在系统表PG_STATISTIC下。执行计划生成器会使用这些统计数据,以确定最有效的执行计划。

它的主要作用是:

  • 优化查询性能:为查询优化器提供数据分布信息,帮助生成更高效的执行计划。
  • 提高查询计划准确性:使优化器能更准确地估算不同查询路径的成本。
  • 支持索引选择:帮助优化器决定是否使用索引以及使用哪个索引。

注意事项

  • 如果没有指定参数,ANALYZE会分析当前数据库中的每个表和分区表。同时也可以通过指定table_name、column和partition_name参数把分析限定在特定的表、列或分区表中。
  • 能够执行ANALYZE特定表的用户,包括表的所有者、表所在数据库的所有者、通过GRANT被授予该表上ANALYZE权限的用户或者被授予了gs_role_analyze_any角色的用户以及有SYSADMIN属性的用户。
  • 在百分比采样收集统计信息时,用户需要被授予ANALYZE和SELECT权限。
  • 开启分区统计信息参数enable_analyze_partition,对分区表设置表级incremental_analyze参数,会先对无统计信息或有数据变化的分区执行ANALYZE,然后通过合并分区统计信息方式生成分区主表的统计信息。
  • 仅8.1.1及以上集群版本支持在匿名块、事务块、函数或存储过程内对单表进行ANALYZE操作。
  • 对于ANALYZE全库,库中各表的ANALYZE处于不同的事务中,所以不支持在匿名块、事务块、函数或存储过程内对全库执行ANALYZE。
  • 统计信息的回滚操作不支持PG_CLASS中相关字段的回滚。
  • 全局临时表在每个会话的ANALYZE的统计信息独立。每个会话都有自己的统计信息。
  • ANALYZE|ANALYSE VERIFY用于检测数据库中普通表(行存表、列存表)的数据文件是否损坏,目前此命令暂不支持HDFS表。
  • ANALYZE VERIFY操作处理的大多为异常场景检测需要使用RELEASE版本。ANALYZE VERIFY场景不触发远程读,因此远程读参数不生效。对于关键系统表出现错误被系统检测出页面损坏时,将直接报错不再继续检测。
  • 单次新增、修改量占表总量10%以上场景,需在业务中增加显式Analyze操作。
  • 更多开发设计规范参见总体开发设计规范

语法格式

  • 收集表的统计信息。
    1
    2
    { ANALYZE | ANALYSE } [ { VERBOSE | LIGHT | FORCE | PREDICATE } ]
        [ table_name [ ( column_name [, ...] ) ] ];
    
  • 收集分区的统计信息。
    1
    2
    3
    { ANALYZE | ANALYSE } [ { VERBOSE | LIGHT | FORCE } ]
        [ table_name [ ( column_name [, ...] ) ] ]
        PARTITION ( partition_name ) ;
    
    • 普通分区表目前支持针对某个分区的统计信息的语法,但功能上不支持针对某个分区的统计信息收集。对指定分区执行ANALYZE,会有相应的WARNING提示。
    • 不支持使用临时采样表来收集分区的统计信息。
    • 不支持分区上的多列统计信息和表达式统计信息。
  • 收集外表的统计信息。
    1
    2
    { ANALYZE | ANALYSE } [ VERBOSE ]
        { foreign_table_name | FOREIGN TABLES };
    
  • 收集多列统计信息。
    1
    2
    {ANALYZE | ANALYSE} [ VERBOSE ]
        table_name (( column_1_name, column_2_name [, ...] ));
    
    • 收集多列统计信息时,请设置GUC参数default_statistics_target为负数,以使用百分比采样方式。
    • 每组多列统计信息最多支持32列。
    • 不支持收集多列统计信息的表:系统表、HDFS外表复制表、全局临时表。
  • 检测当前库的数据文件。
    1
    {ANALYZE | ANALYSE} VERIFY {FAST|COMPLETE};
    
    • 支持对全库进行操作,由于涉及的表较多,建议以重定向保存结果gsql -d database -p port -f "verify.sql"> verify_warning.txt 2>&1
    • 不支持HDFS表(内表和外表),不支持临时表和unlog表。
    • 只有外部表提示NOTICE,内部表的检测会包含在它所依赖的外部表,不对外显示。
    • 此命令的处理可容错ERROR级别的处理。由于debug版本的Assert可能会导致core无法继续执行命令,建议在release模式下操作。
    • 对于全库操作时,当关键系统表出现损坏则直接报错,不再继续执行。
  • 检测表和索引的数据文件。
    1
    {ANALYZE | ANALYSE} VERIFY {FAST|COMPLETE} table_name|index_name [CASCADE];
    
    • 支持对普通表的操作和索引表的操作,但不支持对索引表index使用CASCADE操作。原因是CASCADE模式用于处理主表的所有索引表,当单独对索引表进行检测时,无需使用CASCADE模式。
    • 不支持HDFS表(内表和外表),不支持临时表和unlog表。
    • 对于主表的检测会同步检测主表的内部表,例如toast表、cudesc表等。
    • 当提示索引表损坏时,建议使用reindex命令进行重建索引操作。
  • 检测表分区的数据文件。
    1
    {ANALYZE | ANALYSE} VERIFY {FAST|COMPLETE} table_name PARTITION {(partition_name)}[CASCADE];
    
    • 支持对表的单独分区进行检测操作,但不支持对索引表index使用CASCADE操作。
    • 不支持HDFS表(内表和外表),不支持临时表和unlog表。

参数说明

表1 ANALYZE | ANALYSE参数说明

参数

描述

取值范围

VERBOSE

启用VERBOSE后,ANALYZE会发出进度信息,表明目前正在处理的表。各种有关表的统计信息也会打印出来。

-

LIGHT

轻量化模式下对表收集的统计信息保存到内存中,不写入系统表,执行时对表加一级锁,该选项请加括号使用,例如ANALYZE (LIGHT) t1

-

FORCE

FORCE模式支持表的统计信息被锁定的情况下进行强制执行ANALYZE,该选项请加括号使用,例如ANALYZE (FORCE) t1。

-

PREDICATE

PREDICATE模式表示只计算当前识别到的谓词列的统计信息,该参数仅9.1.0.100及以上集群版本支持。是否支持谓词列的ANALYZE操作由GUC参数analyze_predicate_column_threshold控制,取值为0表示关闭,大于0表示开启谓词列收集功能,且仅对列数大于等于此取值的表进行谓词列ANALYZE。

该选项请加括号使用,例如ANALYZE (PREDICATE) xxx。

谓词信息是在查询解析阶段收集,动态采样也支持谓词列采样。

-

table_name

需要分析的特定表的表名(可能会带模式名),如果省略,将对数据库中的所有表(非外部表)进行分析。

对于ANALYZE收集统计信息,目前仅支持行存表、列存表、HDFS表、ORC格式的OBS外表、CARBONDATA格式的OBS外表、协同分析的外表。

表名长度不超过63个字符,以字母或下划线开头,可包含字母、数字、下划线、$、#。

column_name

需要分析特定列的列名,默认为所有列。

已有的列名,格式为:column_1_name,column_2_name,column_3_name....

partition_name

表示分析该分区表的统计信息。目前语法上支持分区表做ANALYZE,但功能实现上暂不支持对指定分区统计信息的分析。

字符串,要符合分区名的命名规范。

foreign_table_name

需要分析的特定外表的表名(可能会带模式名),该表的数据存放于HDFS分布式文件系统中。

字符串,要符合外表的命名规范。

FOREIGN TABLES

分析所有当前用户权限下,数据位于HDFS分布式文件系统中的HDFS外表。

字符串,要符合HDFS外表的命名规范。

index_name

需要分析的特定索引表的表名(可能会带模式名)。

字符串,要符合索引表的命名规范。

FAST|COMPLETE

不同模式下,对行存表和列存表进行校验。

  • 行存表
    • FAST模式下,主要对于行存表的CRC和page header进行校验,如果校验失败则会告警;
    • COMPLETE模式下,主要对行存表的指针、tuple进行解析校验。
  • 列存表
    • FAST模式下,主要对于列存表的CRC和magic进行校验,如果校验失败则会告警;
    • COMPLETE模式下,主要对列存表的CU进行解析校验。

CASCADE

CASCADE模式下会对当前表的所有索引进行检测处理。

-

示例

  • 使用ANALYZE语句更新表customer_info统计信息:
    1
    ANALYZE customer_info;
    
  • 使用ANALYZE VERBOSE语句更新表customer_info统计信息,并输出表的相关信息:
    1
    2
    3
    4
    5
    ANALYZE VERBOSE customer_info;
    INFO:  analyzing "cstore.pg_delta_3394584009"(cn_5002 pid=53078)
    INFO:  analyzing "public.customer_info"(cn_5002 pid=53078)
    INFO:  analyzing "public.customer_info" inheritance tree(cn_5002 pid=53078)
    ANALYZE
    
  • 更新表customer_info中特定列name,email的统计信息:
    1
    ANALYZE customer_info (name, email);
    
  • 使用轻量化模式更新表customer_info的统计信息。
    1
    ANALYZE (LIGHT) customer_info;
    
  • 使用强制模式更新表customer_info的统计信息,即使表已被锁定。
    1
    ANALYZE (FORCE) customer_info;
    
  • 只更新谓词列的统计信息,只会对当前为止收集到的谓词列进行采样,最后在查询业务稳定后使用。
    1
    ANALYZE (PREDICATE) customer_info;
    

    通过函数pg_stat_get_predicate_columns可以查询当前已收集了表的哪些谓词列,注意以下示例的表名为“customer_info”,实际执行时请替换表名。

    1
    SELECT pr.attnum,pa.attname FROM pg_catalog.pg_stat_get_predicate_columns('customer_info'::regclass) pr LEFT JOIN pg_attribute pa ON pa.attrelid='customer_info'::regclass AND pa.attnum = pr.attnum;
    

相关文档