ANALYZE
更新时间:2026-06-25
ANALYZE
收集有关一个数据库的统计信息。
语法
SQL
1 ANALYZE [VERBOSE] [table [ (column [, ...] ) ]]
2
3 ANALYZE [VERBOSE] {root_partition|leaf_partition} [ (column [, ...] )]
4
5 ANALYZE [VERBOSE] ROOTPARTITION {ALL | root_partition [ (column [, ...] )]}
6 ```
7
8
9
10## 描述
11
12`ANALYZE`收集有关数据库中表内容的统计信息,并将结果存储在系统表*pg_statistic*中。随后,P数据库使用这些统计信息来帮助确定最有效的查询执行计划。
13
14
15 如果不使用任何参数,则`ANALYZE`会收集当前数据库中每个表的统计信息。 可以指定表名称以收集单个表的统计信息。也可以指定一组列名,在这种情况下,仅收集这些列的统计信息。
16
17 `ANALYZE`不会收集外部表的统计信息。
18
19
20 对于分区表,`ANALYZE`在叶子分区上收集其他统计信息,即HyperLogLog(HLL)统计信息。HLL统计信息用于得出针对分区表的查询的不同值(NDV)数量。
21
22 - 当汇总多个叶子分区的NDV估计值时,HLL统计信息比标准表统计信息生成更准确的NDV估计值。
23
24 - 更新HLL统计信息时,仅在已更改的叶子分区上才需要`ANALYZE`操作。
25
26 如果叶子子分区数据已更改,或者叶子子分区已与另一个表交换,则`ANALYZE`是必需的。
27
28
29 重要:如果要在启用ORCA优化器的分区表上执行查询(默认设置),则必须使用`ANALYZE`或`ANALYZE ROOTPARTITION`命令在分区表的根分区上收集统计信息。
30
31
32 注意:还可以使用PalopgMPP数据库实用程序`analyzedb`更新表统计信息。`analyzedb` 可以同时更新多个表的统计信息。 该实用程序还可以检查表统计信息并仅在统计信息不是当前统计信息或不存在时更新统计信息。
33
34
35
36
37
38## 参数
39
40该SQL命令参数说明见下
41
42 `{ root_partition | leaf_partition } [ (column [, ...] ) ]`
43 : 收集分区表的统计信息,包括HLL统计信息。 HLL统计信息仅在叶子分区上收集。
44
45 `ANALYZE root_partition`, 收集所有叶子分区和根分区的统计信息。
46
47 `ANALYZE leaf_partition`, 收集有关叶子分区的统计信息。
48 默认情况下,如果指定叶子分区,并且所有其他叶子分区都具有统计信息,则`ANALYZE`更新根分区统计信息。
49 如果不是所有叶子子分区都具有统计信息,则`ANALYZE`记录有关没有统计信息的叶子子分区的信息。
50
51 `ROOTPARTITION [ALL]`
52 : 仅基于分区表中的数据收集分区表的根分区上的统计信息。 如果可能,`ANALYZE`使用叶子分区统计信息生成根分区统计信息。否则,`ANALYZE`通过对叶子分区数据进行采样来收集统计信息。 未在叶子分区上收集统计信息,仅对数据进行采样。
53 不会收集HLL统计信息。
54
55 指定`ROOTPARTITION`时,必须指定ALL或分区表的名称。: 如果将`ROOTPARTITION`指定为`ALL`,则会收集数据库中所有分区表的根分区的统计信息。如果数据库中没有分区表,则会返回一条消息,指出没有分区表。对于不是分区表的表,不会收集统计信息。
56
57 如果使用`ROOTPARTITION`指定表名,并且该表不是分区表,则不会为该表收集任何统计信息,并且会返回警告消息。
58
59 `ROOTPARTITION`子句不适用于`VACUUM ANALYZE`。 `VACUUM ANALYZE ROOTPARTITION`命令返回错误。
60
61 运行`ANALYZE ROOTPARTITION`的时间类似于分析具有相同数据的非分区表的时间,因为`ANALYZE ROOTPARTITION`仅采样叶子分区数据。
62
63 对于分区表 *sales_curr_yr*,此示例命令仅在分区表的根分区上收集统计信息。
64
65 ``` sql
66 ANALYZE ROOTPARTITION sales_curr_yr;
67 ```
68
69 此示例`ANALYZE`命令收集有关数据库中所有分区表的根分区的统计信息。
70
71 ``` sql
72 ANALYZE ROOTPARTITION ALL;
73 ```
74
75 `VERBOSE`
76 : 启用显示进度消息。 启用显示进度消息。 指定时,`ANALYZE` 发出此信息
77
78 * 正在处理的表。
79
80 * 执行该查询以生成示例表。
81
82 * 要为其计算统计信息的列。
83
84 * 发出以收集单个列的不同统计信息的查询。
85
86 * 收集的统计信息。
87
88 `table`
89 : 要分析的特定表的名称(可能是模式限定的)。 如果省略,则分析当前数据库中的所有常规表(而不是外部表)。
90
91 `column`
92 : 要分析的特定列的名称。 默认为所有列。
93
94
95
96注意
97: * 仅在明确选择外表时才进行分析。 并非所有外部数据包装器都支持`ANALYZE`。如果表的包装器不支持`ANALYZE`,则该命令将显示警告并且不执行任何操作。
98
99 最好定期或在对表内容进行重大更改之后立即运行`ANALYZE`。准确的统计信息有助于PalopgMPP数据库选择最合适的查询计划,从而提高查询处理的速度。
100 只读数据库的常见策略是在一天的低使用时间内每天运行一次 `VACUUM` 和`ANALYZE`。
101 (如果有大量更新活动,这是不够的。)您可以使用`sc_toolkit`模式中的`sc_stats_missing`视图来检查缺少统计信息的表:
102
103 ``` sql
104 SELECT * from sc_toolkit.sc_stats_missing;
105 ```
106
107 `ANALYZE`要求对目标表进行`SHARE UPDATE EXCLUSIVE`锁定。 此锁与以下锁冲突:`SHARE UPDATE EXCLUSIVE`, `SHARE`, `SHARE ROW EXCLUSIVE`, `EXCLUSIVE`, `ACCESS EXCLUSIVE`。
108
109 如果您在不包含数据的表上运行`ANALYZE`,则不会为该表收集统计信息。
110 例如,如果您对具有统计信息的表执行`TRUNCATE`操作,然后对该表运行`ANALYZE`,则统计信息不会更改。
111
112
113 对于分区表,如果分区表具有大量已分析的分区,而只有几个叶子分区具有分区,则指定要分析的表部分,根分区或子分区(叶子分区表)可能会有用 改变了。
114
115
116 * 当使用`CREATE TABLE`命令创建分区表时,PalopgMPP数据库将创建您指定的表(根分区或父表),并根据您指定的分区层次结构(子表)创建表层次结构。
117
118
119
120 * 在根分区表上运行`ANALYZE`时,将收集所有叶子分区的统计信息。叶子子分区是PalopgMPP数据库创建供子表使用的子表层次结构中的最低级表。
121
122 * 在叶子分区上运行`ANALYZE`时,仅收集该叶子分区和根分区的统计信息。如果叶子分区中的数据已更改(例如,您对叶子子分区数据进行了重大更新或交换了叶子子分区),则可以在叶子子分区上运行`ANALYZE`来收集表统计信息。默认情况下,如果所有其他叶子分区都具有统计信息,则该命令将更新根分区统计信息。
123
124 例如,如果您在具有大量分区的分区表上收集统计信息,然后仅在几个叶子分区中更新数据,则可以仅在那些分区上运行`ANALYZE`来更新分区的统计信息和根分区的统计信息。
125
126 * 在不是叶子分区的子表上运行`ANALYZE`时,不会收集统计信息。
127
128 例如,可以创建一个分区表,其中包含2006年至2016年的分区以及每年每个月的子分区。如果在2013年的子表上运行`ANALYZE`,则不会收集任何统计信息。如果在2013年3月在叶子分区上运行`ANALYZE`,则仅收集该叶子分区的统计信息。
129
130 * 对于包含已被交换以使用外部表的叶子分区的分区表,`ANALYZE`不会收集外部表分区的统计信息:
131
132 * 如果在外部表分区上运行`ANALYZE`,则不会分析该分区。
133
134 * 如果在根分区上运行`ANALYZE`或`ANALYZE ROOTPARTITION`,则不对外部表分区进行采样,并且根表统计信息不包括外部表分区。
135
136 * 如果指定了`VERBOSE`子句,则会显示一条参考消息:`skipping external table`。
137
138 * 配置参数`optimizer_analyze_root_partition`影响何时在分区表的根分区上收集统计信息。如果该参数为`on`(默认值),则在运行`ANALYZE`时,不需要`ROOTPARTITION`关键字来收集根分区上的统计信息。在根分区上运行`ANALYZE`或在分区表的子叶分区上运行`ANALYZE`且其他子叶分区具有统计信息时,将收集根分区统计信息。如果该参数是`off`,则必须运行`ANALZYE ROOTPARTITION`来收集根分区统计信息。
139
140 * `ANALYZE`收集的统计信息通常包括每列中一些最常用值的列表以及显示每列中近似数据分布的直方图。如果`ANALYZE`认为它们不重要(例如,在唯一键列中没有公共值),或者列数据类型不支持适当的运算符,则可以忽略其中一个或两个。
141
142 * 对于大型表,`ANALYZE`会从表内容中随机抽取一个样本,而不是检查每一行。这样就可以在很短的时间内分析非常大的表。但是请注意,统计信息仅是近似的,并且每次运行`ANALYZE`都会略有变化,即使实际的表内容没有变化。这可能会导致`EXPLAIN`所显示的计划者估算成本发生细微变化。在极少数情况下,这种不确定性将导致查询优化器在`ANALYZE`运行之间选择不同的查询计划。为了避免这种情况,请通过调整`default_statistics_target`配置参数来提高`ANALYZE`收集的统计信息的数量,或者通过使用`ALTER TABLE ... ALTER COLUMN ... SET (n_distinct ...)`。目标值设置最常用值列表中的最大条目数和直方图中的最大bin数。默认目标值是100,但是可以向上或向下调整该值以权衡规划器估计的准确性与`ANALYZE`v所花费的时间以及`pg_statistic`中占用的空间量。特别是,将统计目标设置为零会禁用该列的统计收集。对于从未用作查询的`WHERE`,`GROUP BY`或`ORDER BY`子句一部分的列,执行此操作可能很有用,因为计划器将不会使用此类列的统计信息。
143
144 * 要分析的列中最大的统计信息目标确定为准备统计信息而采样的表行数。 增加目标会导致进行`ANALYZE`所需的时间和空间成比例增加。
145
146 * `ANALYZE`估计的值之一是出现在每列中的不同值的数量。 因为仅检查了行的子集,所以即使使用最大可能的统计目标,此估计有时也可能非常不准确。如果此错误导致查询计划不正确,则可以手动确定更准确的值,然后与`ALTER TABLE ... ALTER COLUMN ... SET STATISTICS DISTINCT`一起安装。
147
148 * 当P数据库执行`ANALYZE`操作以收集表的统计信息并检测到所有采样的表数据页均为空(不包含有效数据)时,PalopgMPP数据库将显示一条消息,指出应该执行`VACUUM FULL`操作。 如果采样页为空,则表统计信息将不准确。 对表进行大量更改(例如删除大量行)后,页面将变为空。 `VACUUM FULL`操作可删除空白页,并允许`ANALYZE`操作收集准确的统计信息。
149
150 * 如果表没有统计信息,则服务器配置参数`sc_enable_relsize_collection`将控制Palopg查询优化器使用默认统计信息文件还是使用`pg_relation_size`函数估计表的大小。
151
152 * 默认情况下,如果统计信息不可用,Palopg优化器将使用默认的统计信息文件来估计行数。
153
154
155
156## 示例
157
158收集表`mytable`的统计信息:
159
160 ``` sql
161 ANALYZE mytable;
162 ```
163
164
165
166兼容性说明
167: SQL标准中没有`ANALYZE`语句。
168
169
170
171相关SQL命令
172: `ALTER TABLE`, `EXPLAIN`, `VACUUM`, `analyzedb`工具
评价此篇文章
