我有一个非常大的表,400MM 记录,通常只接收插入。但是,最近我必须对记录进行大量更新才能完成任务。这会创建很多死元组。我已将全局配置更新为以下内容:
autovacuum_vacuum_scale_factor = 0
autovacuum_vacuum_threshold = 10000
autovacuum_vacuum_cost_limit = 2000
autovacuum_max_workers = 6
有了这些设置,我的意图是,每当死元组超过 10,000 条记录时,自动清理就会清理它。
但是,我发现当表忙于其他插入等时,死元组计数不会改变。它保持固定在某个死元组计数。只有当 db 活动在夜间减慢时,autovacuum 才能正常工作。
我需要 autovacuum 全天积极处理死元组。我将如何做到这一点?我需要增加 max_workers 数量吗?
更新:用户@Laurenz Albe 建议我运行一些带有和不带有死元组的性能数字来展示性能差异。
我将提供 sql 查询和 EXPLAIN(ANALYZE, BUFFERS) 结果。我更改了表的名称和组键以保护隐私。
EXPLAIN (ANALYZE, BUFFERS)
SELECT ld.upid,
MAX(ld.lid)
INTO _tt_test_with_dead_tuples
FROM big_table ld
GROUP BY ld.upid;
-- >>> 大约 1%(383.2MM 中的 3.648MM)死元组,结果如下。
HashAggregate (cost=25579746.07..25584552.97 rows=480690 width=8) (actual time=5966760.520..5975279.359 rows=16238417 loops=1)
Group Key: upid
Buffers: shared hit=3015376 read=16753169 dirtied=1759802 written=1360458
-> Seq Scan on big_table ld (cost=0.00..23642679.05 rows=387413405 width=8) (actual time=0.024..5593239.148 rows=383753513 loops=1)
Buffers: shared hit=3015376 read=16753169 dirtied=1759802 written=1360458
Planning time: 2.677 ms
Execution time: 6012319.846 ms
-- >>> 有 0 个死元组,结果如下。
HashAggregate (cost=25558409.48..25562861.52 rows=445204 width=8) (actual time=825662.640..835163.398 rows=16238417 loops=1)
Group Key: upid
Buffers: shared hit=15812 read=19753809
-> Seq Scan on big_table ld (cost=0.00..23628813.32 rows=385919232 width=8) (actual time=0.020..533386.128 rows=383753513 loops=1)
Buffers: shared hit=15812 read=19753809
Planning time: 10.109 ms
Execution time: 843319.731 ms