首页/数据/SQL 速查/PostgreSQL 分批删除写法与膨胀控制
变更与事务52 条

PostgreSQL 分批删除写法与膨胀控制

PostgreSQL 没有 DELETE LIMIT:用 ctid 子查询分批;删除只是标记死元组,空间回收依赖 VACUUM,批量删除要配合清理策略。

SQL 速查数据更新于 2026-10-12

示例

示例
DELETE FROM logs l
USING (
    SELECT ctid FROM logs
    WHERE created_at < now() - interval '90 days'
    ORDER BY id
    LIMIT 5000
) b
WHERE l.ctid = b.ctid;
死元组DELETE/UPDATE 旧版本留在表中,autovacuum 负责回收
膨胀长期高频删除的大表要检查 n_dead_tup 与表大小占比
替代按时间分区的表可直接 DETACH/DROP 分区,代价更低

易错点

  • 只在业务上删除却从不关注 vacuum:dead tuple 堆积后查询与写入都变慢(页面膨胀、索引效率下降)
  • 每批太小会放大事务开销,太大又回到长事务问题;先观察单批耗时再定批量

数据来源与参考

  • PostgreSQL Documentation · DELETE
  • PostgreSQL Documentation · Routine Vacuuming
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌