ANALYZE收集表内容的统计信息,然后把结果保存在系统表pg_statistic里。 随后,查询规划器就可以使用这些统计帮助判断查询的最佳规划。
如果没有参数,ANALYZE检查当前数据库里的所有表。 如果有参数,ANALYZE只检查那个表。 你还可以给出一列字段名字,这个时候只收集那些字段的统计信息
在默认的PostgreSQL配置中,autovacuum守护进程 (参阅Section 23.1.5)负责在初次加载数据时自动分析表。 因为它们会改变整个常规操作。当autovacuum关闭时, 周期性地运行ANALYZE,或者在对表的大部分内容做了更改之后 马上运行它是个好习惯, 准确的统计信息将帮助规划器选择最合适的查询规划,并因此改善查询处理的速度。 一种比较经常采用的策略是每天在低负荷的时候运行一次VACUUM 和ANALYZE 。
ANALYZE只需要在目标表上有一个读取锁,因此它可以和表上的其它活动并发地运行。
ANALYZE收集的统计信息通常包括每个字段最常用数值的列表以及显示每个字段里数据近似分布的包线图。 如果ANALYZE认为它们都没有什么用(比如在一个拥有唯一约束的字段上没有公共的数值)或者是该字段数据类型不支持相关的操作符, 那么它们都可以忽略。在Chapter 23中有关于统计的更多信息。
对于大表,ANALYZE采集表内容的一个随机抽样做统计, 而不是检查每一行。这样就保证了即使是在很大的表上也只需要很少时间就可以完成分析。 不过,要注意的是统计只是近似的结果, 而且每次运行ANALYZE都会导致EXPLAIN显示 的规划器的预期开销有一些小变化,即使表内容实际上没有改变也这样。 在极少的情况下,此非决定论会引发规划器在ANALYZE运行后引发查询 计划更改。为了避免这个问题,可以提高ANALYZE收集的统计数量, 像下面描述的那样。
分析的广度可以通过用调整default_statistics_target配置变量, 或者是以每字段为基础通过用ALTER TABLE ... ALTER COLUMN ... SET STATISTICS(参阅ALTER TABLE)设置每字段的统计目标来控制。 目标数值设置最常用数值列表中的记录的最大数目以及包线图中的最大块数。 缺省的目标数值是100,不过可以调节这个数值获取规划器计算精度和 ANALYZE运行所需要的时间以及pg_statistic里面占据的空间数目之间的平衡。 特别是,把统计目标设置为零就关闭了该字段的统计收集。 这么做对那些从来不参与到查询的WHERE,GROUP BY, 或者ORDER BY子句里的字段是很有用的,因为规划器不会使用到这样的字段上的统计。
在被分析的字段中最大的统计目标决定统计采样的行数。 增大目标会导致ANALYZE的时候成比例地增大对时间和空间的需求。
One of the values estimated by ANALYZE is the number of distinct values that appear in each column. Because only a subset of the rows are examined, this estimate can sometimes be quite inaccurate, even with the largest possible statistics target. If this inaccuracy leads to bad query plans, a more accurate value can be determined manually and then installed with ALTER TABLE ... ALTER COLUMN ... SET (n_distinct = ...) (see ALTER TABLE). ANALYZE的一个估计值是出现在每列的不同值的数目。因为仅仅 行的一个子集被检查,这个估计值有时会很不准确,甚至是对最大可能的统计目标。 如果这个错误导致了差的查询计划,一个更精确的值可以通过手动确定并且然后通过 ALTER TABLE ... ALTER COLUMN ... SET (n_distinct = ...)安装。 (参阅 ALTER TABLE)。
If the table being analyzed has one or more children, ANALYZE will gather statistics twice: once on the rows of the parent table only, and a second time on the rows of the parent table with all of its children. The autovacuum daemon, however, will only consider inserts or updates on the parent table when deciding whether to trigger an automatic analyze. If that table is rarely inserted into or updated, the inheritance statistics will not be up to date unless you run ANALYZE manually. 若已分析的表有一个或者更多子表,ANALYZE将会收集统计两次: 一次仅仅在父表的行上,第二次是在父表及其所有子表的行上。autovacuum守护进程, 然而,会仅仅考虑在父表上进行插入或者更新,在决定是否触发一个自动分析时。 若果那个表几乎不插入或者更新,继承的统计数据将不再更新,除非您手动运行 ANALYZE。