用ANALYZE更新统计信息
良好查询性能的最重要的先决条件是从表的正确统计信息开始。用ANALYZE
语句更新统计信息让查询规划器能生成最优的查询计划。当表被分析时,有关数据的信息被存储在系统目录表中。如果存储的信息过时,规划器可能会生成低效的计划。
有选择地生成统计信息
不带参数运行ANALYZE
会为数据库中所有的表更新统计信息。这可能会是运行时间非常长的处理,因此不推荐这样做。当数据被改变时,使用者应该有选择地ANALYZE
表。
在大型表上运行ANALYZE
可能需要很长时间。如果在非常大的表的所有列上运行ANALYZE
行不通,使用者可以只使用ANALYZE table(column,
...)
为选择的列生成统计信息。确保包括用在连接、WHERE
子句、SORT
子句、GROUP BY
子句或者HAVING
子句中的列。
对于一个分区表,使用者可以只在更改过的分区(例如,使用者增加一个分区)上运行ANALYZE
。注意对于分区表,使用者可以在父(主)表上或者叶子节点(实际存储数据和统计信息的分区文件)上运行ANALYZE
。子分区表的中间文件没有存储数据或统计信息,因此在其上运行ANALYZE
没有效果。使用者可以在pg_partitions
系统目录中寻找分区表的名字:
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
会禁用自动统计信息收集。
对于分区表,如果数据从分区表的顶层父表插入,则自动统计信息收集不会被触发。但是如果数据直接被插入在分区表的叶子表(存储数据的地方)中,则自动统计信息收集会被触发。
上级主题: 系统监控和维护