PostgreSQL 清理了一个大 table

PostgreSQL vacuuming a big table

我有 Postgres 9.4.7,我有一个很大的 table ~100M 行和 20 列。 table 查询是每分钟 1.5k 次选择、150 次插入和 300 次更新,但没有删除。这是我的 autovacuum 配置:

autovacuum_analyze_scale_factor 0
autovacuum_analyze_threshold 5000
autovacuum_vacuum_scale_factor 0
autovacuum_vacuum_threshold 5000
autovacuum_max_workers6
autovacuum_naptime5秒

在我的案例中,数据库几乎总是处于不断清理的状态。当一个吸尘会话结束时,另一个吸尘会话开始。

所以主要问题是: 有没有一种常用的方法来清理大 tables?

还有一些其他问题。

标准真空不扫描整个 table 并且 'analyze' 仅扫描 30k 行。所以在相同的负载下我应该有一个恒定的执行时间,是真的吗? 我真的需要分析 table 吗?频繁 'analyze' 可以对大型 table 的查询计划进行任何有用的更改吗?

真空

VACUUM reclaims storage occupied by dead tuples.

所以它只改变受影响的页面,但它会扫描整个 table。

这就是您可能所说的 "Standard vacuum"。现在如果你有 9.6,那么

VACUUM will skip pages based on the visibility map

分析

ANALYZE 扫描 depends on table size and default_statistics_target set per instance 或每个 table 的数据量 - 它本身不是 30K:

For large tables, ANALYZE takes a random sample of the table contents, rather than examining every row... change slightly each time ANALYZE is run, even if the actual table contents did not change. This might result in small changes in the planner's estimated costs shown by EXPLAIN.

所以如果你想要更多 stable 的 EXPLAIN 运行 结果,比如

alter table ... alter COLUMN ... set STATISTICS 200;

或增加default_statistics_target,否则太频繁分析有更多机会更改计划。

还有一件事 - 您有 5K 门槛。在具有 100000K 行的 table 中,它是 0.002% - 对吗?所以比例是0.00002?而默认值是 0.2 或 0.1 中的一个......这让我觉得你的阈值可能太低了。 运行 确实建议更频繁地吸尘,但这里看起来太频繁了。比默认情况下的频率高一千倍...