ANALYZE — 收集数据库统计信息
ANALYZE [ (option
[, ...] ) ] [table_and_columns
[, ...] ] whereoption
can be one of: VERBOSE [boolean
] SKIP_LOCKED [boolean
] BUFFER_USAGE_LIMITsize
andtable_and_columns
is: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
指定是否应启用或禁用所选选项。您可以编写 TRUE
、ON
或 1
来启用该选项,以及编写 FALSE
、OFF
或 0
来禁用该选项。 boolean
值也可以省略,在这种情况下,假定为 TRUE
。
size
以千字节为单位指定内存量。大小也可以指定为包含数字大小的字符串,后跟以下任何一个内存单位:B
(字节)、kB
(千字节)、MB
(兆字节)、GB
(千兆字节)或 TB
(太字节)。
table_name
要分析的特定表的名称(可能带有模式限定)。如果省略,则会分析当前数据库中的所有常规表、分区表和物化视图(但不包括外表)。如果指定的表是分区表,则会更新分区表整体的继承统计信息和各个分区的统计信息。
column_name
要分析的特定列的名称。默认为所有列。
当指定 VERBOSE
时,ANALYZE
会发出进度消息,指示当前正在处理哪个表。还会打印有关表的各种统计信息。
要分析一个表,通常必须对该表具有 MAINTAIN
权限。但是,数据库所有者可以分析其数据库中的所有表,除了共享目录。 ANALYZE
将跳过调用用户无权分析的任何表。
仅当明确选择外表时,才会分析外表。并非所有外部数据包装器都支持 ANALYZE
。如果表的包装器不支持 ANALYZE
,则该命令会打印警告并且不执行任何操作。
在默认的 PostgreSQL 配置中,自动清理守护程序(请参阅 第 24.1.6 节)负责在首次加载数据时以及在常规操作中更改时自动分析表。禁用自动清理后,最好定期运行 ANALYZE
,或者在对表的内容进行重大更改后立即运行。准确的统计信息将帮助规划器选择最合适的查询计划,从而提高查询处理的速度。对于以读取为主的数据库,一种常见的策略是在一天中低使用率的时间段运行一次 VACUUM
和 ANALYZE
。(如果有大量的更新活动,这可能是不够的。)
当 ANALYZE
运行时,search_path 会临时更改为 pg_catalog, pg_temp
。
ANALYZE
只需要目标表上的读取锁,因此它可以与表上的其他非 DDL 活动并行运行。
ANALYZE
收集的统计信息通常包括每列中一些最常见值的列表和显示每列中近似数据分布的直方图。如果 ANALYZE
认为它们不重要(例如,在唯一键列中,没有常见的值)或者列数据类型不支持适当的运算符,则可以省略其中一个或两个。有关统计信息的更多信息,请参阅 第 24 章。
对于大型表,ANALYZE
会对表内容进行随机采样,而不是检查每一行。这使得即使是非常大的表也可以在短时间内进行分析。但是请注意,统计信息只是近似值,并且每次运行 ANALYZE
时都会略有变化,即使实际的表内容没有更改。这可能会导致 EXPLAIN
显示的规划器估计成本略有变化。在极少数情况下,这种不确定性会导致在运行 ANALYZE
后,规划器选择的查询计划发生更改。为避免这种情况,请增加 ANALYZE
收集的统计信息量,如下所述。
可以通过调整 default_statistics_target 配置变量来控制分析的范围,也可以通过使用 ALTER TABLE ... ALTER COLUMN ... SET STATISTICS
设置每列统计信息目标来控制分析的范围。目标值设置最常见值列表中的最大条目数和直方图中的最大箱数。默认目标值为 100,但是可以向上或向下调整此值,以在规划器估计的准确性与 ANALYZE
所用的时间和 pg_statistic
中占用的空间之间进行权衡。特别是,将统计信息目标设置为零会禁用该列的统计信息收集。对于从不用作查询的 WHERE
、GROUP BY
或 ORDER BY
子句的一部分的列,这样做可能很有用,因为规划器将不会使用此类列的统计信息。
正在分析的列中最大的统计信息目标确定为准备统计信息而采样的表行数。增加目标会导致执行 ANALYZE
所需的时间和空间成比例增加。
ANALYZE
估计的值之一是每个列中出现的不同值的数量。由于只检查了行的子集,因此即使使用最大的统计目标,此估计值有时也可能非常不准确。如果这种不准确导致了错误的查询计划,则可以手动确定更准确的值,然后使用 ALTER TABLE ... ALTER COLUMN ... SET (n_distinct = ...)
进行安装。
如果正在分析的表具有继承子表,则 ANALYZE
会收集两组统计信息:一组仅针对父表的行,另一组包括父表及其所有子表的行。当规划处理整个继承树的查询时,需要第二组统计信息。在这种情况下,子表本身不会单独分析。然而,在决定是否触发该表的自动分析时,autovacuum 守护进程只会考虑对父表本身进行的插入或更新。如果该表很少插入或更新,除非您手动运行 ANALYZE
,否则继承统计信息将不会是最新的。
对于分区表,ANALYZE
通过从所有分区中采样行来收集统计信息;此外,它将递归到每个分区并更新其统计信息。每个叶子分区只分析一次,即使是多级分区也是如此。不会收集仅针对父表(没有来自其分区的数据)的统计信息,因为使用分区时保证它是空的。
autovacuum 守护进程不处理分区表,如果只修改子表,它也不处理继承父表。通常需要定期手动运行 ANALYZE
,以保持表层次结构的统计信息是最新的。
如果任何子表或分区是外表,其外部数据包装器不支持 ANALYZE
,则在收集继承统计信息时会忽略这些表。
如果正在分析的表完全为空,则 ANALYZE
将不会记录该表的新统计信息。任何现有的统计信息都将被保留。
每个运行 ANALYZE
的后端都将在 pg_stat_progress_analyze
视图中报告其进度。有关详细信息,请参阅第 27.4.1 节。
SQL 标准中没有 ANALYZE
语句。
以下语法在 PostgreSQL 11 版本之前使用,并且仍然受支持
ANALYZE [ VERBOSE ] [ table_and_columns
[, ...] ]
如果您在文档中发现任何不正确、与您使用特定功能的经验不符或需要进一步澄清的内容,请使用此表单报告文档问题。