{"Entry":{"collection":"storage","key":"storage-hot","name":"Heap-Only Tuples ( HOT )","aliases":[],"metadata":{"aliases":[],"category":"Physical structures","content_hash":"7833c1bc0b75b0b66a9b5673cd12bbbc69e7755b583ddd702ed0f2ff9abb1fdc","derived_content_hash":"6a89bdfd7ec51b16d1e500b262013bec52093a9df8c1d00e60b92c4d3708d898","imported_at":"2026-09-30T00:40:47.094754+08:00","name":"Heap-Only Tuples ( HOT )","name_zh":"","slug":"storage-hot","summary":"To allow for high concurrency, PostgreSQL uses multiversion concurrency control ( MVCC ) to store rows. However, MVCC has some downsides for update queries. Specifically, updates require new versions of rows to be added to tables. This can also require new index entries for each updated row, and removal of old versions of rows and their index entries can be expensive."}},"Definition":{"Collection":"storage","Key":"storage-hot","SourceDatabase":"center","Version":"18","SourceTable":"storage_structure","SourceKey":"storage-hot","SourceRevision":"555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f","Facts":{"comparison_data":{"layouts":[]},"comparison_hash":"27341929154bfb55531f03501322b65af719c5561f3c4ddc9528a14aa4df69b5","description":["To allow for high concurrency, PostgreSQL uses multiversion concurrency control ( MVCC ) to store rows. However, MVCC has some downsides for update queries. Specifically, updates require new versions of rows to be added to tables. This can also require new index entries for each updated row, and removal of old versions of rows and their index entries can be expensive."],"description_zh":"为了支持高并发， PostgreSQL 使用 多版本并发控制 （ MVCC ）来存储行。不过， MVCC 对更新查询也有一些缺点。具体来说，更新需要向表中加入新的行版本。这还可能要求为每个被更新的行新增索引条目，而移除旧的行版本及其索引条目可能代价很高。 为了帮助降低更新的开销， PostgreSQL 提供了一种名为堆内元组（ HOT ）的优化。该优化在以下情况下可行： 在这种情况下，堆内元组提供两项优化： 要提高页面拥有足够空间进行 HOT 更新的可能性，你可以降低表的 fillfactor 。即使不这样做， HOT 更新也仍然会发生，因为新行会自然迁移到新页面，而那些具有足够空闲空间容纳新行版本的现有页面也会被利用。系统视图 pg_stat_all_tables 可以用来监控 HOT 更新和非 HOT 更新的发生情况。","description_zh_html":"\u003cp\u003e存储结构 storage-hot。\u003c/p\u003e\u003ch3\u003e同版本中文手册节选\u003c/h3\u003e\u003cp\u003e\n  为了支持高并发，\u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e 使用\u003ca class=\"link\" href=\"/zh/docs/18/mvcc-intro.html\"\u003e多版本并发控制\u003c/a\u003e（\u003cacronym class=\"acronym\"\u003eMVCC\u003c/acronym\u003e）来存储行。不过，\u003cacronym class=\"acronym\"\u003eMVCC\u003c/acronym\u003e 对更新查询也有一些缺点。具体来说，更新需要向表中加入新的行版本。这还可能要求为每个被更新的行新增索引条目，而移除旧的行版本及其索引条目可能代价很高。\n \u003c/p\u003e\u003cp\u003e\n  为了帮助降低更新的开销，\u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e 提供了一种名为堆内元组（\u003cacronym class=\"acronym\"\u003eHOT\u003c/acronym\u003e）的优化。该优化在以下情况下可行：\n\n  \u003c/p\u003e\u003cp\u003e\n\n  在这种情况下，堆内元组提供两项优化：\n\n  \u003c/p\u003e\u003cp\u003e\n  要提高页面拥有足够空间进行 \u003cacronym class=\"acronym\"\u003eHOT\u003c/acronym\u003e 更新的可能性，你可以降低表的\n  \u003ca class=\"link\" href=\"/zh/docs/18/sql-createtable.html#RELOPTION-FILLFACTOR\"\u003e\u003ccode class=\"literal\"\u003efillfactor\u003c/code\u003e\u003c/a\u003e。即使不这样做，\u003cacronym class=\"acronym\"\u003eHOT\u003c/acronym\u003e 更新也仍然会发生，因为新行会自然迁移到新页面，而那些具有足够空闲空间容纳新行版本的现有页面也会被利用。系统视图\n  \u003ca class=\"link\" href=\"/zh/docs/18/monitoring-stats.html#MONITORING-PG-STAT-ALL-TABLES-VIEW\"\u003epg_stat_all_tables\u003c/a\u003e\n  可以用来监控 HOT 更新和非 HOT 更新的发生情况。\n \u003c/p\u003e\u003cp\u003e\u003ca href=\"/zh/docs/18/storage-hot.html\"\u003e查看完整中文手册与上下文\u003c/a\u003e。\u003c/p\u003e","facts":[{"label":"Definition scope","value":"Same-version core physical storage documentation"}],"facts_zh":[{"label":"定义范围","value":"同版本核心物理存储文档"}],"manual_html":"\u003cdiv class=\"sect1\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch2 class=\"title\"\u003e66.7. Heap-Only Tuples (HOT) \u003c/h2\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eTo allow for high concurrency, \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e uses \u003ca class=\"link\" href=\"/docs/18/mvcc-intro.html\" title=\"13.1. Introduction\"\u003emultiversion concurrency control\u003c/a\u003e (MVCC) to store rows. However, MVCC has some downsides for update queries. Specifically, updates require new versions of rows to be added to tables. This can also require new index entries for each updated row, and removal of old versions of rows and their index entries can be expensive.\u003c/p\u003e\n\u003cp\u003eTo help reduce the overhead of updates, \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e has an optimization called heap-only tuples (HOT). This optimization is possible when:\u003c/p\u003e\n\u003cdiv class=\"itemizedlist\"\u003e\n\u003cul class=\"itemizedlist\"\u003e\n\u003cli class=\"listitem\"\u003e\n\u003cp\u003eThe update does not modify any columns referenced by the table's indexes, not including summarizing indexes. The only summarizing index method in the core \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e distribution is \u003ca class=\"link\" href=\"/docs/18/brin.html\" title=\"65.5. BRIN Indexes\"\u003eBRIN\u003c/a\u003e.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli class=\"listitem\"\u003e\n\u003cp\u003eThere is sufficient free space on the page containing the old row for the updated row.\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/div\u003e\n\u003cp\u003eIn such cases, heap-only tuples provide two optimizations:\u003c/p\u003e\n\u003cdiv class=\"itemizedlist\"\u003e\n\u003cul class=\"itemizedlist\"\u003e\n\u003cli class=\"listitem\"\u003e\n\u003cp\u003eNew index entries are not needed to represent updated rows, however, summary indexes may still need to be updated.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli class=\"listitem\"\u003e\n\u003cp\u003eWhen a row is updated multiple times, row versions other than the oldest and the newest can be completely removed during normal operation, including \u003ccode class=\"command\"\u003eSELECT\u003c/code\u003es, instead of requiring periodic vacuum operations. (Indexes always refer to the \u003ca class=\"link\" href=\"/docs/18/storage-page-layout.html\" title=\"66.6. Database Page Layout\"\u003epage item identifier\u003c/a\u003e of the original row version. The tuple data associated with that row version is removed, and its item identifier is converted to a redirect that points to the oldest version that may still be visible to some concurrent transaction. Intermediate row versions that are no longer visible to anyone are completely removed, and the associated page item identifiers are made available for reuse.)\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/div\u003e\n\u003cp\u003eYou can increase the likelihood of sufficient page space for HOT updates by decreasing a table's \u003ca class=\"link\" href=\"/docs/18/sql-createtable.html#RELOPTION-FILLFACTOR\"\u003e\u003ccode class=\"literal\"\u003efillfactor\u003c/code\u003e\u003c/a\u003e. If you don't, HOT updates will still happen because new rows will naturally migrate to new pages and existing pages with sufficient free space for new row versions. The system view \u003ca class=\"link\" href=\"/docs/18/monitoring-stats.html#MONITORING-PG-STAT-ALL-TABLES-VIEW\" title=\"27.2.19. pg_stat_all_tables\"\u003epg_stat_all_tables\u003c/a\u003e allows monitoring of the occurrence of HOT and non-HOT updates.\u003c/p\u003e\n\u003c/div\u003e","manual_path":"/docs/18/storage-hot.html","related":[{"label":"Table AM","url":"/wiki/tableam/?v=18"},{"label":"Storage Parameters","url":"/wiki/relopts/?v=18"}],"release":{"channel":"stable","label":"18.6","major":"18","ref":"https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2","revision":"555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f"},"sections":[],"sections_zh":[],"signature":"","sources":[{"label":"PostgreSQL 18 English manual","path":"storage-hot.html","sha256":"10b16ef2342681e7c41be6a1bc1e3ea1cb3ba9f592be29dcc941fba269713bfa","url":"/docs/18/storage-hot.html"}],"tables":[],"tables_zh":[],"zh_from":{"authored_translation":"source-derived-identity","body_sha256":"50b4ecc0d6fcf53d9593ecd45ff72ab0839454f21c8ea33929ef3578406bb044","kind":"same-version-chinese-manual-with-source-derived-identity","manual":{"anchor":"","build_id":107,"extraction":"concept-introduction","fragment_sha256":"55a9ed3b1f8b94ee538608420299606b3d10c5953ad95040bdfd5ca021ffe3d8","locale":"zh-Hans","page_key":"storage-hot.html","source_hash":"f5bf1f6d5a1e756423924a704ecc86d3bf3d694f4438807bfd7cbb94d62730c2","source_revision":"unknown:rendered-translation-baseline","translated_from_revision":null,"translation_revision":"git:b1b500221dbe5437cfca004d6b04d3f6e422765d;html-sha256:08e987a66af27b98444a8057c256314eafa13611a3fb9e888214fc436824244b","url":"/zh/docs/18/storage-hot.html","version":"18"},"runtime_rerun":false,"source_facts_revision":"555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f"}},"ManualEvidence":{"manual_path":"/docs/18/storage-hot.html","release":{"channel":"stable","label":"18.6","major":"18","ref":"https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2","revision":"555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f"},"sources":[{"label":"PostgreSQL 18 English manual","path":"storage-hot.html","sha256":"10b16ef2342681e7c41be6a1bc1e3ea1cb3ba9f592be29dcc941fba269713bfa","url":"/docs/18/storage-hot.html"}]},"MeasuredEvidence":{}},"Text":{"Collection":"storage","Key":"storage-hot","SourceDatabase":"center","Version":"18","Locale":"en","Title":"Heap-Only Tuples ( HOT )","Summary":"To allow for high concurrency, PostgreSQL uses multiversion concurrency control ( MVCC ) to store rows. However, MVCC has some downsides for update queries. Specifically, updates require new versions of rows to be added to tables. This can also require new index entries for each updated row, and removal of old versions of rows and their index entries can be expensive.","BodyHTML":"\u003cdiv\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch2\u003e66.7. Heap-Only Tuples (HOT) \u003c/h2\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eTo allow for high concurrency, \u003cspan\u003ePostgreSQL\u003c/span\u003e uses \u003ca href=\"/docs/18/mvcc-intro.html\" rel=\"nofollow\"\u003emultiversion concurrency control\u003c/a\u003e (MVCC) to store rows. However, MVCC has some downsides for update queries. Specifically, updates require new versions of rows to be added to tables. This can also require new index entries for each updated row, and removal of old versions of rows and their index entries can be expensive.\u003c/p\u003e\n\u003cp\u003eTo help reduce the overhead of updates, \u003cspan\u003ePostgreSQL\u003c/span\u003e has an optimization called heap-only tuples (HOT). This optimization is possible when:\u003c/p\u003e\n\u003cdiv\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eThe update does not modify any columns referenced by the table\u0026#39;s indexes, not including summarizing indexes. The only summarizing index method in the core \u003cspan\u003ePostgreSQL\u003c/span\u003e distribution is \u003ca href=\"/docs/18/brin.html\" rel=\"nofollow\"\u003eBRIN\u003c/a\u003e.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eThere is sufficient free space on the page containing the old row for the updated row.\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/div\u003e\n\u003cp\u003eIn such cases, heap-only tuples provide two optimizations:\u003c/p\u003e\n\u003cdiv\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eNew index entries are not needed to represent updated rows, however, summary indexes may still need to be updated.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eWhen a row is updated multiple times, row versions other than the oldest and the newest can be completely removed during normal operation, including \u003ccode\u003eSELECT\u003c/code\u003es, instead of requiring periodic vacuum operations. (Indexes always refer to the \u003ca href=\"/docs/18/storage-page-layout.html\" rel=\"nofollow\"\u003epage item identifier\u003c/a\u003e of the original row version. The tuple data associated with that row version is removed, and its item identifier is converted to a redirect that points to the oldest version that may still be visible to some concurrent transaction. Intermediate row versions that are no longer visible to anyone are completely removed, and the associated page item identifiers are made available for reuse.)\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/div\u003e\n\u003cp\u003eYou can increase the likelihood of sufficient page space for HOT updates by decreasing a table\u0026#39;s \u003ca href=\"/docs/18/sql-createtable.html#RELOPTION-FILLFACTOR\" rel=\"nofollow\"\u003e\u003ccode\u003efillfactor\u003c/code\u003e\u003c/a\u003e. If you don\u0026#39;t, HOT updates will still happen because new rows will naturally migrate to new pages and existing pages with sufficient free space for new row versions. The system view \u003ca href=\"/docs/18/monitoring-stats.html#MONITORING-PG-STAT-ALL-TABLES-VIEW\" rel=\"nofollow\"\u003epg_stat_all_tables\u003c/a\u003e allows monitoring of the occurrence of HOT and non-HOT updates.\u003c/p\u003e\n\u003c/div\u003e","SourceRevision":"555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f","ContentHash":"dbcc50433d9d69531088707e71448327b6d365ad573cd862d6a660d840593f01","Payload":{"description":["To allow for high concurrency, PostgreSQL uses multiversion concurrency control ( MVCC ) to store rows. However, MVCC has some downsides for update queries. Specifically, updates require new versions of rows to be added to tables. This can also require new index entries for each updated row, and removal of old versions of rows and their index entries can be expensive."],"manual_html":"\u003cdiv class=\"sect1\"\u003e\n\u003cdiv class=\"titlepage\"\u003e\n\u003cdiv\u003e\n\u003cdiv\u003e\n\u003ch2 class=\"title\"\u003e66.7. Heap-Only Tuples (HOT) \u003c/h2\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cp\u003eTo allow for high concurrency, \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e uses \u003ca class=\"link\" href=\"/docs/18/mvcc-intro.html\" title=\"13.1. Introduction\"\u003emultiversion concurrency control\u003c/a\u003e (MVCC) to store rows. However, MVCC has some downsides for update queries. Specifically, updates require new versions of rows to be added to tables. This can also require new index entries for each updated row, and removal of old versions of rows and their index entries can be expensive.\u003c/p\u003e\n\u003cp\u003eTo help reduce the overhead of updates, \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e has an optimization called heap-only tuples (HOT). This optimization is possible when:\u003c/p\u003e\n\u003cdiv class=\"itemizedlist\"\u003e\n\u003cul class=\"itemizedlist\"\u003e\n\u003cli class=\"listitem\"\u003e\n\u003cp\u003eThe update does not modify any columns referenced by the table's indexes, not including summarizing indexes. The only summarizing index method in the core \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e distribution is \u003ca class=\"link\" href=\"/docs/18/brin.html\" title=\"65.5. BRIN Indexes\"\u003eBRIN\u003c/a\u003e.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli class=\"listitem\"\u003e\n\u003cp\u003eThere is sufficient free space on the page containing the old row for the updated row.\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/div\u003e\n\u003cp\u003eIn such cases, heap-only tuples provide two optimizations:\u003c/p\u003e\n\u003cdiv class=\"itemizedlist\"\u003e\n\u003cul class=\"itemizedlist\"\u003e\n\u003cli class=\"listitem\"\u003e\n\u003cp\u003eNew index entries are not needed to represent updated rows, however, summary indexes may still need to be updated.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli class=\"listitem\"\u003e\n\u003cp\u003eWhen a row is updated multiple times, row versions other than the oldest and the newest can be completely removed during normal operation, including \u003ccode class=\"command\"\u003eSELECT\u003c/code\u003es, instead of requiring periodic vacuum operations. (Indexes always refer to the \u003ca class=\"link\" href=\"/docs/18/storage-page-layout.html\" title=\"66.6. Database Page Layout\"\u003epage item identifier\u003c/a\u003e of the original row version. The tuple data associated with that row version is removed, and its item identifier is converted to a redirect that points to the oldest version that may still be visible to some concurrent transaction. Intermediate row versions that are no longer visible to anyone are completely removed, and the associated page item identifiers are made available for reuse.)\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/div\u003e\n\u003cp\u003eYou can increase the likelihood of sufficient page space for HOT updates by decreasing a table's \u003ca class=\"link\" href=\"/docs/18/sql-createtable.html#RELOPTION-FILLFACTOR\"\u003e\u003ccode class=\"literal\"\u003efillfactor\u003c/code\u003e\u003c/a\u003e. If you don't, HOT updates will still happen because new rows will naturally migrate to new pages and existing pages with sufficient free space for new row versions. The system view \u003ca class=\"link\" href=\"/docs/18/monitoring-stats.html#MONITORING-PG-STAT-ALL-TABLES-VIEW\" title=\"27.2.19. pg_stat_all_tables\"\u003epg_stat_all_tables\u003c/a\u003e allows monitoring of the occurrence of HOT and non-HOT updates.\u003c/p\u003e\n\u003c/div\u003e","related":[{"label":"Table AM","url":"/wiki/tableam/?v=18"},{"label":"Storage Parameters","url":"/wiki/relopts/?v=18"}],"sections":[],"tables":[]}},"RequestedLocale":"en","Fallback":false,"Versions":["11","12","13","14","15","16","17","18","19","20"],"Locales":["en","zh-Hans"],"Signatures":null,"Spellings":null,"SQLState":null,"Evidence":null}
