9.3 9.4 9.5 9.6 10 11 12 13 14 15 Current(16) 17
问题报告 纠错本页面

ANALYZE

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

Synopsis

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

其中 option 可以是以下之一:

    VERBOSE [ boolean ]
    SKIP_LOCKED [ boolean ]
    BUFFER_USAGE_LIMIT size

并且 table_and_columns 是:

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

描述

ANALYZE收集一个数据库中的表的内容的统计信息,并且将结果存储在pg_statistic系统目录中。接下来,查询规划器会使用这些统计信息来帮助确定查询最有效的执行计划。

如果没有table_and_columns列表,则ANALYZE处理当前用户有权分析的当前数据库中的每个表和物化视图。使用列表,ANALYZE仅处理那些表。还可以给出表的列名列表,在这种情况下,仅收集这些列的统计信息。

参数

VERBOSE

允许显示进度消息。

SKIP_LOCKED

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

BUFFER_USAGE_LIMIT

指定 缓冲区访问策略 的环形缓冲区大小,用于ANALYZE。此大小用于计算作为此策略 一部分将被重用的共享缓冲区数量。0会禁用 缓冲区访问策略的使用。当未指定此选项时, 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会发出进度消息来指示当前正在处理哪个表。还会打印有关那些表的多种统计信息。

注解

要分析一个表,通常必须拥有该表的MAINTAIN权限。 但是,数据库所有者被允许分析其数据库中的所有表,除了共享目录。 ANALYZE会跳过调用用户无权分析的任何表。

只有被显式选中时才会分析外部表。并非所有外部数据包装器都支持ANALYZE。如果表的包装器不支持ANALYZE,该命令会打印一个警告并且什么也不做。

在默认的PostgreSQL配置中,自动清理守护进程(见Section 24.1.6)会在表第一次载入数据或者用常规操作改变时负责表的自动分析。当启用自动清理时,定期运行ANALYZE是个好主意,或者可以在表内容做了大的修改后运行ANALYZE。准确的统计信息将帮助规划器选择最合适的查询计划,从而提升查询处理的速度。主读数据库的一般策略是在一天中使用量最低时运行一次VACUUMANALYZE(如果有大量的更新动作则是不够的)。

While ANALYZE is running, the search_path is temporarily changed to 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 BY或者ORDER BY子句中从不出现的列上这样做会有所帮助,因为规划器用不上这些列上的统计信息。

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

ANALYZE所估算的值之一是出现在每个列中的可区分值。因为只会检查行的一个子集,即便使用最大的统计信息目标,这种估计有时也可能很不精确。如果这种不精确导致不好的查询计划,可以手工确定一个更精确的值并且用ALTER TABLE ... ALTER COLUMN ... SET (n_distinct = ...)设置该值。

如果被分析的表具有继承子表, ANALYZE会收集两组统计信息:一组仅针对父表的行,另一组包括父表及其所有子表的行。 当规划处理整个继承树的查询时,需要这第二组统计信息。 在这种情况下,子表本身不会被单独分析。 然而,自动清理守护程序只会考虑对父表本身的插入或更新,以决定是否为该表触发自动分析。 如果很少向该表插入或更新数据,则除非手动运行ANALYZE,否则继承统计信息将不会是最新的。

对于分区表,ANALYZE通过对所有分区的行进行抽样来收集统计信息; 此外,它将递归地进入每个分区并更新其统计信息。即使有多级分区,每个叶分区也只分析一次。 对于仅包含父表(没有来自其分区的数据)的情况不收集统计信息,因为使用分区保证其为空。

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

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

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

每个运行ANALYZE的后端将会在pg_stat_progress_analyze 视图中报告其进度。详细参考Section 27.4.1

兼容性

SQL 标准中没有ANALYZE语句。

以下语法在 PostgreSQL 11 版本之前使用,且仍然支持:

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

另见

VACUUM, vacuumdb, Section 19.4.4, Section 24.1.6, Section 27.4.1