及時準確地統計信息是查詢優化器生成高效查詢計劃的必要條件。云原生數據倉庫 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;