用ANALYZE更新统计信息

良好查询性能的最重要的先决条件是从表的正确统计信息开始。用ANALYZE语句更新统计信息让查询规划器能生成最优的查询计划。当表被分析时,有关数据的信息被存储在系统目录表中。如果存储的信息过时,规划器可能会生成低效的计划。

有选择地生成统计信息

不带参数运行ANALYZE会为数据库中所有的表更新统计信息。这可能会是运行时间非常长的处理,因此不推荐这样做。当数据被改变时,使用者应该有选择地ANALYZE表。

在大型表上运行ANALYZE可能需要很长时间。如果在非常大的表的所有列上运行ANALYZE行不通,使用者可以只使用ANALYZE table(column, …)为选择的列生成统计信息。确保包括用在连接、WHERE子句、SORT子句、GROUP BY子句或者HAVING子句中的列。

对于一个分区表,使用者可以只在更改过的分区(例如,使用者增加一个分区)上运行ANALYZE。注意对于分区表,使用者可以在父(主)表上或者叶子节点(实际存储数据和统计信息的分区文件)上运行ANALYZE。子分区表的中间文件没有存储数据或统计信息,因此在其上运行ANALYZE没有效果。使用者可以在pg_partitions系统目录中寻找分区表的名字:

  1. SELECT partitiontablename from pg_partitions WHERE tablename='parent_table;

提升统计信息质量

在生成统计信息所花的时间和统计信息的质量或者准确性之间存在着权衡。

为了允许大型表能在合理的时间内被分析完,ANALYZE会对表内容做随机采样而不是检查每一行。要对所有表列增加采样,可调整default_statistics_target配置参数。其目标值取值范围从1到1000,默认的目标值是25。default_statistics_target变量默认会被应用到所有的列。更大的目标值会增加执行ANALYZE所需的时间,但是可以提升查询规划器的估计质量。对于带有不规则数据模式的列尤其如此。default_statistics_target可以在Master或者会话级别设置,并且要求重新载入配置。

gp_analyze_relative_error配置参数影响统计信息收集期间的采样率以确定列中的基数。例如,值为0.5等效于50%的错误是可接受的。默认值为0.25。使用gp_analyze_relative_error参数设置对表基数可接受的估计相对误差。如果统计信息对于一个特定的表属性没有产生基数的好的估计,可降低该相对错误分数(接受更小的误差)告诉系统采样更多列。但是,不推荐把这个值降低到低于0.1,因为那样会大量增加ANALYZE花费的时间。

何时运行ANALYZE

在下列时机运行ANALYZE:

  • 装载数据后;
  • CREATE INDEX操作后;
  • 在显著更改底层数据的INSERT、UPDATE以及DELETE操作之后。

ANALYZE仅在表上要求一个读锁,因此它可以与其他数据库活动并行运行。但不要在执行装载、INSERT、UPDATE、DELETE以及CREATE INDEX操作期间会运行ANALYZE。

配置自动统计信息收集

gp_autostats_mode配置参数与gp_autostats_on_change_threshold参数一起决定何时触发自动分析操作。当自动统计信息收集被触发时,规划器会为查询增加一个ANALYZE步骤。

gp_autostats_mode默认为on_no_stats,这会为任何没有统计信息的表上的CREATE TABLE AS SELECT、INSERT或者COPY操作触发统计信息收集。

把gp_autostats_mode设置为on_change时,只有当受影响的行数超过由gp_autostats_on_change_threshold定义的阈值时才会触发统计信息收集,该阈值参数的默认值为2147483647。on_change设置下能触发自动统计信息收集的操作有:CREATE TABLE AS SELECT、UPDATE、DELETE、INSERT以及COPY。

将gp_autostats_mode设置为none会禁用自动统计信息收集。

对于分区表,如果数据从分区表的顶层父表插入,则自动统计信息收集不会被触发。但是如果数据直接被插入在分区表的叶子表(存储数据的地方)中,则自动统计信息收集被触发。

上级主题: 系统监控和维护