Skip to content

ANALYZE

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

概要

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

where option can be one of:

    VERBOSE [ boolean ]
    SKIP_LOCKED [ boolean ]
    BUFFER_USAGE_LIMIT size

and table_and_columns is:

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

说明

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

如果没有*table_and_columns*列表,ANALYZE将处理当前用户有权分析的当前数据库中的每个表和物化视图。有了列表,ANALYZE只处理那些表。还可以为表提供一个列名列表,在这种情况下,只收集那些列的统计信息。

当选项列表被括号包围时,可以按任何顺序编写选项。括号语法在PostgreSQL11 中添加;不带括号的语法已弃用。

参数

VERBOSE

启用进度消息显示。

SKIP_LOCKED

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

BUFFER_USAGE_LIMIT

ANALYZE 指定 缓冲区访问策略 环形缓冲区大小。此大小用于计算将作为此策略一部分重新使用的共享缓冲区的数量。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

要分析的特定表的名称(可能具有模式限定)。如果省略,将分析当前数据库中的所有常规表、分区表和物化视图(但不包括外部表)。如果指定表是分区表,则将更新分区表整体的继承统计信息和各个分区的统计信息。

column_name

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

输出

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

注释

要分析表,通常必须是表的拥有者或超级用户。但是,允许数据库所有者分析其数据库中的所有表,共享目录除外。(共享目录的限制意味着只有超级用户才能执行真正的数据库范围ANALYZE。)ANALYZE会跳过调用用户无权分析的任何表。

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

在默认PostgreSQL配置中,自动清理守护进程(请参阅第 25.1.6 节)负责在表首次加载数据时以及在常规操作过程中表发生更改时自动分析表。当禁用自动清理时,最好定期运行ANALYZE,或者刚在表的内容中进行重大更改后运行。准确的统计信息将帮助规划器选择最合适的查询计划,从而提高查询处理速度。对于只读数据库,一种常见的策略是在一天中使用率较低的时间运行VACUUMANALYZE一次。(如果更新活动较多,这将不足够。)

ANALYZE仅需要对目标表进行读锁定,因此它可以与表上的其他活动并行运行。

ANALYZE收集的统计信息通常包括每列中一些最常见值的列表,以及显示每列中近似数据分布的直方图。如果ANALYZE认为这些内容无趣(例如,在唯一键列中没有常见值)或列数据类型不支持适当的操作符,则可以省略其中一个或两个。有关统计信息的更多信息,请参阅第 25 章

对于大型表,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通过从所有分区中抽样行来收集统计信息;此外,它将递归到每个分区并更新其统计信息。即使是多级分区,每个叶分区也只分析一次。不会仅为父表(不含其分区中的数据)收集统计信息,因为使用分区可保证其为空。

自动清理守护进程不处理分区表,也不处理仅修改子项的继承父项。通常需要定期运行手动ANALYZE,以使表层次结构的统计信息保持最新。

如果任何子表或分区是外键数据包装器不支持ANALYZE的外键表,则在收集继承统计信息时将忽略这些表。

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

每个运行ANALYZE的后端将在pg_stat_progress_analyze视图中报告其进度。有关详细信息,请参见第 28.4.1 节

兼容性

SQL 标准中没有ANALYZE语句。

另请参见

VACUUMvacuumdb第 20.4.4 节第 25.1.6 节第 28.4.1 节