为了实现高并发,PostgreSQL 使用 多版本并发控制 (MVCC) 来存储行。然而,MVCC对更新查询有一些不利影响。具体来说,更新需要将行的最新版本添加到表中。这还可能需要为每个更新的行创建新的索引条目,并且删除旧版本的行及其索引条目可能成本很高。
为了帮助减少更新的开销,PostgreSQL 有一个名为仅堆元组 (HOT) 的优化。当满足以下条件时,此优化是可能的:
更新不修改由表索引引用的任何列,不包括汇总索引。核心 PostgreSQL 发行版中唯一的汇总索引方法是 BRIN。
包含旧行的页面上有足够的可用空间容纳更新后的行。
在这种情况下,仅堆元组提供了两个优化:
更新的行不需要新的索引条目,但是,汇总索引可能仍需要更新。
当一行被多次更新时,除了最旧和最新的行版本之外的其他行版本可以在正常操作(包括 SELECT
s)期间被完全删除,而无需进行定期的 VACUUM 操作。(索引始终引用原始行版本的 页面项标识符。与该行版本关联的元组数据被删除,其项标识符被转换为指向可能仍对某些并发事务可见的最旧版本的重定向。不再对任何人可见的中间行版本被完全删除,并且关联的页面项标识符可供重用。)
您可以通过减小表的 fillfactor
来增加用于HOT更新的页面空间的可能性。如果您不这样做,HOT更新仍将发生,因为新行自然会迁移到新页面,并且现有页面将有足够的可用空间容纳新行版本。系统视图 pg_stat_all_tables 允许监控 HOT 和非 HOT 更新的发生情况。
如果您在文档中看到任何不正确、与您对特定功能的经验不符或需要进一步澄清的内容,请使用 此表单 报告文档问题。