版本:
目录导航

66.7. 仅存储在堆中的元组(HOT#

为了实现高并发,PostgreSQL使用多版本并发控制MVCC)来存储行。然而,MVCC对于更新查询有一些不足之处。具体来说,更新需要向表中添加新版本的行。这也可能需要为每个更新的行添加新的索引条目,并且删除旧版本的行及其索引条目可能会很昂贵。

为了帮助减少更新的开销,PostgreSQL有一种称为 堆内元组(HOT)的优化。该优化在以下情况下可用:

  • 更新不会修改表的索引所引用的任何列,不包括汇总索引。核心 PostgreSQL发行版中唯一的汇总索引方法是 BRIN

  • 包含旧行的页面上有足够的空闲空间用于存放更新后的行。

在这种情况下,堆内元组提供了两种优化:

  • 不需要新的索引条目来表示更新的行,但汇总索引可能仍需更新。

  • 当一行被多次更新时,除最旧和最新版本外的行版本可以在正常操作中 完全移除,包括SELECT操作,而不需要定期的清理 操作。(索引始终引用原始行版本的 页面项标识符。与该行版本 关联的元组数据被移除,其项标识符被转换为指向可能仍对某些并发事务 可见的最旧版本的重定向。对任何人都不可见的中间行版本被完全移除, 其关联的页面项标识符被释放以供重用。)

您可以通过减少表的 fillfactor来增加HOT更新有足够页面空间的 可能性。如果不这样做,HOT更新仍然会发生,因为新行会自然迁移到新 页面以及现有页面中有足够空闲空间的新行版本。系统视图pg_stat_all_tables 允许监控HOT和非HOT更新的发生情况。