ANALYZE
— 收集数据库内容统计信息
ANALYZE [ (option
[, ...] ) ] [table_and_columns
[, ...] ] whereoption
can be one of: VERBOSE [boolean
] SKIP_LOCKED [boolean
] BUFFER_USAGE_LIMITsize
andtable_and_columns
is: [ 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
指定 缓冲访问策略 环形缓冲器的大小。此大小用于计算将作为此策略一部分重用的共享缓冲区的数量。0
禁用 Buffer Access Strategy
的使用。未指定此选项时,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
要分析的特定表的名称(可能已模式限定)。如果省略,则分析当前数据库中的所有常规表、分区表和物化视图(但不包括外部表)。如果 ONLY
指定在表名前,则只分析该表。如果未指定 ONLY
,则分析该表及其所有继承的子表或分区(如果有)。可以选择在表名后指定 *
以明确表示要分析继承的子表(或分区)。
column_name
要分析的特定列的名称。默认为所有列。
当指定 VERBOSE
时,ANALYZE
会发出进度消息,指示当前正在处理哪个表。还会打印关于表的各种统计信息。
要分析一个表,通常必须拥有该表的 MAINTAIN
权限。但是,数据库所有者可以分析其数据库中的所有表,但共享目录除外。ANALYZE
会跳过调用用户无权分析的任何表。
外部表仅在明确选择时才会被分析。并非所有外部数据包装器都支持 ANALYZE
。如果表的包装器不支持 ANALYZE
,该命令会打印警告并什么都不做。
在默认的 PostgreSQL 配置中,自动清理守护进程(请参阅 第 24.1.6 节)负责在表首次加载数据时以及在正常操作过程中发生变化时自动分析表。当禁用自动清理时,最好定期运行 ANALYZE
,或在对表内容进行重大更改后运行。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
设置每个列的统计信息目标来按列进行控制。目标值设置了最常见值列表中的最大条目数和直方图中的最大 bin 数。默认目标值为 100,但可以根据需要调整该值,以权衡规划器估算的准确性与 ANALYZE
所需的时间以及 pg_statistic
中的空间占用量。特别地,将统计信息目标设置为零会禁用该列的统计信息收集。对于从不在查询的 WHERE
、GROUP BY
或 ORDER 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
视图中报告其进度。有关详细信息,请参阅 第 27.4.1 节。
SQL 标准中没有 ANALYZE
语句。
以下语法在 PostgreSQL 11 版本之前使用,并且仍然受支持
ANALYZE [ VERBOSE ] [ table_and_columns
[, ...] ]
如果您在文档中发现任何不正确、与您在使用特定功能时的体验不符或需要进一步澄清的内容,请使用 此表单 报告文档问题。