受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发版本: devel

ANALYZE

ANALYZE — 收集数据库的统计信息

Synopsis

ANALYZE [ ( option [, ...] ) ] [ table_and_columns [, ...] ]

其中option可以是下列之一:

    VERBOSE [ boolean ]
    SKIP_LOCKED [ boolean ]
    BUFFER_USAGE_LIMIT size

其中table_and_columns是:

    [ ONLY ] table_name [ * ] [ ( column_name [, ...] ) ]

描述

ANALYZE收集数据库中各表内容的统计信息,并将结果存储到pg_statistic 系统目录中。随后,查询规划器会使用这些统计信息来帮助确定查询的最高效执行计划。

如果没有给出table_and_columns 列表,ANALYZE会处理当前数据库中当前用户有权分析的每个表和物化视图。 如果给出了列表,ANALYZE则只处理其中列出的表。还可以为某个表给出列名列表, 这时只会收集这些列的统计信息。

参数

VERBOSE #

启用 INFO 级别的进度消息显示。

SKIP_LOCKED #

指定ANALYZE在开始处理某个关系时,不要等待任何冲突锁被释放: 如果某个关系无法立即获得锁而无需等待,就跳过该关系。请注意,即使使用了此选项, ANALYZE在打开该关系的索引时,或者在从分区、继承子表以及某些类型的外部表获取样本行时, 仍然可能发生阻塞。另外,虽然ANALYZE通常会处理指定分区表的所有分区, 但如果该分区表上存在冲突锁,此选项会导致ANALYZE跳过全部分区。

BUFFER_USAGE_LIMIT #

指定ANALYZE所使用的 缓冲区访问策略(Buffer Access Strategy) 环形缓冲区大小。该大小用于计算在此策略中会被重用的共享缓冲区数量。 0表示禁用Buffer Access Strategy。 如果未指定此选项,ANALYZE会使用 vacuum_buffer_usage_limit中的值。更高的设置可以让 ANALYZE运行得更快,但设置过大可能会把过多其他有用页面从共享缓冲区中逐出。 最小值是128 kB,最大值是16 GB

boolean #

指定打开还是关闭所选选项。你可以写入 TRUEON1 来启用该选项,以及写入FALSEOFF0来禁用它。 boolean值也可以省略, 此时假定为TRUE

size #

指定以千字节为单位的内存大小。也可以把大小写成一个字符串,即数值后跟下列任一种内存单位: B(字节)、kB(千字节)、MB(兆字节)、 GB(吉字节)或TB(太字节)。

table_name #

要分析的特定表的名称(可以用模式限定)。如果省略,则会分析当前数据库中的所有普通表、 分区表和物化视图(但不包括外部表)。如果在表名前指定ONLY, 则只分析该表。如果未指定ONLY,则会分析该表及其所有继承子表或分区 (如果有)。还可以在表名之后指定*,以显式指明要分析继承子表(或分区)。

column_name #

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

输出

指定VERBOSE时,ANALYZE会输出进度消息, 指示当前正在处理哪个表,同时还会打印这些表的各种统计信息。

注解

要分析一个表,通常必须拥有该表上的MAINTAIN权限。 不过,数据库拥有者可以分析其数据库中的所有表,但共享系统目录除外。 ANALYZE会跳过调用用户无权分析的任何表。

只有在显式选中时才会分析外部表。并非所有外部数据包装器都支持ANALYZE。 如果该表的包装器不支持ANALYZE,命令会打印一条警告且不执行任何操作。

在默认的PostgreSQL配置中,自动清理守护进程 (见Section 24.1.6)会在表首次装载数据时,以及在常规运行过程中数据发生变化时, 自动分析这些表。当自动清理被禁用时,最好定期运行ANALYZE, 或者在对表内容做出重大更改之后立即运行。准确的统计信息有助于规划器选择最合适的查询计划, 从而提高查询处理速度。对于以读取为主的数据库,一个常见策略是在每天使用率较低的时段运行一次 VACUUMANALYZE。 (如果更新活动很频繁,这样做仍然不够。)

ANALYZE正在运行时,search_path会被临时改为 pg_catalog, pg_temp

ANALYZE在目标表上只需要获取读锁,因此可以与该表上的其他非 DDL 活动并行运行。

ANALYZE收集的统计信息通常包括每一列中某些最常见值的列表, 以及展示该列近似数据分布的直方图。如果ANALYZE认为这些信息没有意义 (例如在唯一键列中不存在常见值),或者该列的数据类型不支持适当的操作符, 则其中一项或两项都可能被省略。关于统计信息的更多内容,见Chapter 24

对于大型表,ANALYZE会对表内容进行随机采样,而不是检查每一行。 这使得即使是很大的表,也能在较短时间内完成分析。不过要注意,这些统计信息只是近似值, 并且即使实际表内容没有变化,每次运行ANALYZE时统计信息也会略有变化。 这可能导致EXPLAIN中显示的规划器估算代价略有变化。 在少数情况下,这种非确定性会导致规划器在运行ANALYZE之后改用不同的查询计划。 要避免这种情况,可以按下文所述提高ANALYZE收集的统计信息量。

可以通过调整配置变量default_statistics_target来控制分析程度, 也可以针对单个列使用ALTER TABLE ... ALTER COLUMN ... SET STATISTICS设置每列的统计信息目标。目标值会设置最常见值列表中的最大条目数, 以及直方图中的最大桶数。默认目标值是 100,但可以把它调高或调低,以在规划器估算精度、 ANALYZE耗费的时间以及pg_statistic占用的空间之间作出权衡。 特别地,将统计信息目标设置为零会禁用该列的统计信息收集。对于那些从不出现在查询 WHEREGROUP BYORDER BY子句中的列, 这样做可能很有用,因为规划器不会用到这些列的统计信息。

被分析列中最大的统计信息目标决定了为了生成统计信息而需要采样的表行数。 增加该目标会导致执行ANALYZE所需的时间和空间按比例增加。

ANALYZE估算的值之一是每一列中出现的不同值数量。由于只检查了部分行, 即使使用可能的最大统计信息目标,这种估计有时也可能相当不精确。如果这种不精确导致查询计划不佳, 就可以手工确定一个更精确的值,然后用 ALTER TABLE ... ALTER COLUMN ... SET (n_distinct = ...) 把该值设置进去。

如果被分析的表有继承子表,ANALYZE会收集两组统计信息: 一组只针对父表中的行,另一组则同时包含父表及其所有子表中的行。规划处理整个继承树的查询时, 需要第二组统计信息。不过,自动清理守护进程在决定是否为该表触发自动分析时, 只会考虑对父表本身的插入或更新。如果该表很少被插入或更新,那么除非手工运行 ANALYZE,否则继承统计信息就不会保持最新。默认情况下, ANALYZE还会递归地收集并更新每个继承子表的统计信息。 可以使用ONLY关键字来禁用这一行为。

对于分区表,ANALYZE会通过对所有分区中的行进行采样来收集统计信息。 默认情况下,ANALYZE还会递归地收集并更新每个分区的统计信息。 可以使用ONLY关键字来禁用这一行为。

自动清理守护进程不会处理分区表;如果继承体系中只有子表被修改,它也不会处理继承父表。 因此,通常需要定期手工运行ANALYZE,以保持表层次结构的统计信息为最新状态。

如果某些子表或分区是外部表,而其外部数据包装器不支持ANALYZE, 那么在收集继承统计信息时会忽略这些表。

如果被分析的表完全为空,ANALYZE将不会为该表记 录新的统计信息。任何现有统计信息都会被保留。

每个运行ANALYZE的后端都会在 pg_stat_progress_analyze视图中报告其进度。 详见Section 27.4.1

兼容性

SQL 标准中没有ANALYZE语句。

以下语法在 PostgreSQL 11 之前的版本中使用过, 当前仍然受支持:

ANALYZE [ VERBOSE ] [ table_and_columns [, ...] ]

提交更正

如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。