SQL COMMAND · 维护
ANALYZE
收集数据库的统计信息
collect statistics about a database
ANALYZE维护引入 7.2现存至 20 devel6 次语法变更
- 动词
ANALYZE- 对象
—- 分组
- 维护
- 引入版本
- 7.2
- 状态
- 现存
- 语法变更次数
- 6
- 手册小节数
- 6
版本轨迹
相对 PostgreSQL 17:语法概要新增 1 行,移除 0 行。
语法铁道图 PostgreSQL 18
沿轨道从左向右阅读,分岔表示选择,绕行表示可选,回环表示重复。方框为参数,点击带下划线的参数可展开子规则。
option
table_and_columns
锁模式 PostgreSQL 18
具体锁模式取决于操作变体、目标对象和执行阶段;同一命令可同时取得表锁与行锁。查看完整冲突矩阵
SHARE UPDATE EXCLUSIVE· 表级锁ANALYZE:在被分析的目标表上取得此模式。
语法概要
相对 PostgreSQL 17 新增 1 行,移除 0 行;新增行以绿色标记。
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表示禁用缓冲区访问策略。如果未指定此选项,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,或者在对表内容做出重大更改之后立即运行。准确的统计信息有助于规划器选择最合适的查询计划,从而提高查询处理速度。对于以读取为主的数据库,一个常见策略是在每天使用率较低的时段运行一次
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 会收集两组统计信息:一组只针对父表中的行,另一组则同时包含父表及其所有子表中的行。规划处理整个继承树的查询时,需要第二组统计信息。不过,自动清理守护进程在决定是否为该表触发自动分析时,只会考虑对父表本身的插入或更新。如果该表很少被插入或更新,那么除非手工运行
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 [, ...] ]
另见
语法演化
相邻大版本之间的差异,新的在前。版本号链接到对应快照。
PostgreSQL 20← 19正文更新
正文更新PostgreSQL 18← 17语法变化
+ [ ONLY ] table_name [ * ] [ ( column_name [, ...] ) ]正文更新PostgreSQL 17← 16语法变化
− ANALYZE [ ( option [, ...] ) ] [ table_and_columns [, ...] ]− ANALYZE [ VERBOSE ] [ table_and_columns [, ...] ]正文更新PostgreSQL 16← 15语法变化
+ BUFFER_USAGE_LIMIT size正文更新PostgreSQL 14← 13正文更新
正文更新PostgreSQL 12← 11语法变化
+ VERBOSE [ boolean ]+ SKIP_LOCKED [ boolean ]正文更新PostgreSQL 11← 10语法变化
+ ANALYZE [ ( option [, ...] ) ] [ table_and_columns [, ...] ]+ ANALYZE [ VERBOSE ] [ table_and_columns [, ...] ]+ VERBOSE− ANALYZE [ VERBOSE ] [ table_name [ ( column_name [, ...] ) ] ]正文更新PostgreSQL 10← 9.6正文更新
正文更新PostgreSQL 9.6← 9.5正文更新
正文更新PostgreSQL 9.5← 9.4正文更新
正文更新PostgreSQL 9.4← 9.3正文更新
正文更新PostgreSQL 9.2← 9.1语法变化
+ ANALYZE [ VERBOSE ] [ table_name [ ( column_name [, ...] ) ] ]− ANALYZE [ VERBOSE ] [ table [ ( column [, ...] ) ] ]正文更新PostgreSQL 9.0← 8.4正文更新
正文更新PostgreSQL 8.4← 8.3正文更新
正文更新PostgreSQL 8.3← 8.2正文更新
正文更新PostgreSQL 8.1← 8.0正文更新
正文更新PostgreSQL 8.0← 7.4正文更新
正文更新PostgreSQL 7.4← 7.3正文更新
正文更新PostgreSQL 7.3← 7.2正文更新
正文更新PostgreSQL 7.2← 7.1新增此命令
同组命令
| 命令 | 动词 | 对象 | 版本变动 | 最近变更 |
|---|---|---|---|---|
ANALYZE | ANALYZE | — | 186 次 | |
| 收集数据库的统计信息 | 现存 | |||
CHECKPOINT | CHECKPOINT | — | 191 次 | |
| 强制执行一次预写式日志检查点 | 现存 | |||
CLUSTER | CLUSTER | — | 177 次 | |
| 按照一个索引对表进行聚簇 | 现存 | |||
VACUUM | VACUUM | — | 1914 次 | |
| 垃圾收集并按需分析数据库 | 现存 | |||