自动收集统计信息
及时准确地统计信息是查询优化器生成高效查询计划的必要条件。云原生数据仓库 AnalyticDB PostgreSQL 版提供了自动收集统计信息的功能(AUTO ANALYZE)。该功能会根据某张表插入或更新数据的比例自动触发ANALYZE
收集统计信息。现支持异步自动收集统计信息和同步自动收集统计信息两种方式。本文介绍两种自动收集统计信息的工作机制和使用方法。
版本限制
云原生数据仓库 AnalyticDB PostgreSQL 版内核小版本为v1.0.5.0及以上。
如何升级小版本,请参见版本升级。
异步自动收集统计信息
工作机制
异步自动收集统计信息会定期检查存在大量数据插入、更新或删除的表。当满足以下触发规则时,将异步自动执行ANALYZE
命令。
触发规则:数据变更行数 > 表总行数 * 触发比例阈值 + 触发行数阈值。
数据变更行数:该信息在最后一次收集统计信息执行
ANALYZE
后会清零,之后表中有插入、更新、删除数据时会重新统计该信息。表总行数:表的总行数为该表上次执行
ANALYZE
时统计的行数。触发比例阈值:由
autovacuum_analyze_scale_factor
参数控制,默认为10%。触发行数阈值:由
autovacuum_analyze_threshold
参数控制,默认为50行。
即默认情况下:当某张表最后一次收集统计信息后,再次变更约10%的数据时,会自动执行ANALYZE
收集统计信息。
锁冲突
异步自动收集统计信息持有表的四级锁。在异步自动收集统计信息工作期间,如果业务需要持有的锁与AUTO ANALYZE需要获取的锁冲突时,AUTO ANALYZE进程会主动退让锁,不影响业务执行。
分区表
对于分区表,异步自动收集统计信息会按照子分区触发收集,之后会将子分区的统计信息合并到父分区。
查询当前进程
异步自动收集统计信息进程由Auto Vacuum调度。
在AnalyticDB PostgreSQL 6.0版中,使用如下SQL语句查看正在工作的Auto Vacuum进程。
SELECT * FROM pg_stat_activity WHERE query LIKE 'autovacuum%';
在AnalyticDB PostgreSQL 7.0版中,使用如下SQL语句查看正在工作的Auto Vacuum进程。
SELECT * FROM pg_stat_activity WHERE backend_type = 'autovacuum worker';
查询当前需要执行
ANALYZE
的表。下面SQL语句中,
autovacuum_analyze_scale_factor
的参数值为10%,autovacuum_analyze_threshold
的参数值为50。SELECT schemaname, c.relname, c.reltuples, n_mod_since_analyze, last_autoanalyze, (n_mod_since_analyze::float / c.reltuples::float) AS analyze_ratio FROM pg_stat_all_tables s, pg_class c WHERE c.oid = s.relid AND c.reltuples > 50 AND (n_mod_since_analyze::float > 50 + c.reltuples::float * 0.1) ORDER BY (n_mod_since_analyze::float/ c.reltuples::float) DESC;
实例级别阈值说明
阈值名称 | 描述 | 默认值 |
autovacuum_enabled | 是否开启ANALYZE功能。 | TRUE |
autovacuum_naptime | AUTO ANALYZE检查周期。单位:分钟。 | 1 |
autovacuum_analyze_scale_factor | AUTO ANALYZE触发的比例阈值。该数值越大,表示表中变更更多数据时才会触发异步自动收集统计信息。 | 10% |
autovacuum_analyze_threshold | AUTO ANALYZE触发的行数阈值。该数值越大,表示表中数据插入、更新或删除的行数越多,会触发异步自动收集统计信息。单位:行。 | 50 |
autovacuum_max_execute_workers | AUTO ANALYZE的执行并发数。 | max(3,cpucores/2) cpucores为当前实例的单计算节点CPU核数。 |
通常不建议调整实例级别的AUTO ANALYZE参数。如果需要调整某个参数阈值,可以提交工单联系工作人员调整。
表级别阈值说明
阈值名称 | 描述 |
autovacuum_analyze_scale_factor | AUTO ANALYZE触发的比例阈值。该数值越大,表示表中数据插入、更新或删除的比例越高,会触发异步自动收集统计信息。 |
autovacuum_analyze_threshold | AUTO ANALYZE触发的行数阈值。该数值越大,表示表中数据插入、更新或删除的行数越多,会触发异步自动收集统计信息。单位:行。 |
设置阈值
语法
ALTER TABLE <test_table> SET (<autoanalyze_options>=<expect_value>)
参数说明
<test_table>
:需要调整的表的名称。<autoanalyze_options>
:需要调整的AUTO ANALYZE表级别阈值。<expect_value>
:需要调整的值。
使用示例
关闭test表的AUTO ANALYZE。
ALTER TABLE test SET (autovacuum_enabled=false);
说明autovacuum_enabled=false
同时会关闭表的Auto Vacuum功能。建议通过调高触发比例来实现只关闭AUTO ANALYZE。调高test表AUTO ANALYZE的触发比例到80%。
ALTER TABLE test SET (autovacuum_analyze_scale_factor=0.8);
恢复阈值默认值
语法
ALTER TABLE <test_table> RESET (<autoanalyze_options>);
参数说明
<test_table>
:需要调整的表的名称。<autoanalyze_options>
:需要调整的AUTO ANALYZE表级别阈值。
使用示例
恢复test表的AUTO ANALYZE的触发比例为默认值。
ALTER TABLE test RESET (autovacuum_analyze_scale_factor);
同步自动收集统计信息
由于异步自动收集统计信息存在延时(约1分钟),作为异步自动收集统计信息的补充,云原生数据仓库 AnalyticDB PostgreSQL 版也有同步自动收集统计信息的功能。即在表中数据发生变更的命令执行结束前,同步地自动收集统计信息。
同步自动收集信息不支持分区表。
工作机制
同步自动收集统计信息有以下三种模式。
none:禁止同步自动收集统计信息。即所有统计信息的收集需要依赖异步或者手动执行命令完成。
on_no_stats:当对没有统计信息的表执行
CREATE TABLE AS SELECT
、INSERT
或者COPY
时,就会自动收集该表的统计信息。但是除此以外的其他统计信息收集需求,仍然依赖异步或者手动执行命令完成。on_change:执行
CREATE TABLE AS SELECT
、INSERT
、UPDATE
、DELETE
或者COPY
命令时,如果影响的行数超过了gp_autostats_on_change_threshold
内核参数所设置的阈值时,自动触发表的统计信息收集。该模式完全自动化,不需要额外手动执行统计信息收集命令。
阈值说明
参数名称 | 描述 | 默认值 | 取值范围 |
gp_autostats_mode | 适用于除函数或存储过程外的其他表的同步自动收集统计信息。 | on_no_stats |
|
gp_autostats_mode_in_functions | 适用于在函数或存储过程中同步自动收集统计信息。 | none |
|
gp_autostats_on_change_threshold | on_change模式下,如果某个命令影响的行数超过该值,则会在执行命令时同步地执行 | 2147483647 | [0, 2147483647] |
通常不建议调整实例级别的同步自动收集统计信息参数。如果想要调整某个参数阈值,可以在会话级别设置。
会话级别调整设置
可以在会话级别调整同步收集统计信息的相关设置。
当前会话的函数或存储过程中,当对没有统计信息的表执行
CREATE TABLE AS SELECT
、INSERT
或COPY
,以下设置会触发一次自动收集统计信息。SET gp_autostats_mode_in_functions = on_no_stats;
关闭当前会话中同步收集统计信息的设置。
SET gp_autostats_mode_in_functions = on_no_stats; SET gp_autostats_mode = NONE;
当前会话在执行
CREATE TABLE AS SELECT
、INSERT
、UPDATE
、DELETE
或COPY
时,如果某张表变更行数超过十万行,以下设置会同步执行一次统计信息收集。SET gp_autostats_mode = on_change; SET gp_autostats_on_change_threshold = 100000;