doc: add section about heap-only tuples (HOT)
authorBruce Momjian
Fri, 12 Aug 2022 19:05:12 +0000 (15:05 -0400)
committerBruce Momjian
Fri, 12 Aug 2022 19:05:12 +0000 (15:05 -0400)
Reported-by: Jonathan S. Katz
Discussion: https://postgr.es/m/c59ffbd5-96ac-a5a5-a401-14f627ca1405@postgresql.org

Backpatch-through: 11

doc/src/sgml/acronyms.sgml
doc/src/sgml/btree.sgml
doc/src/sgml/catalogs.sgml
doc/src/sgml/config.sgml
doc/src/sgml/indexam.sgml
doc/src/sgml/indices.sgml
doc/src/sgml/monitoring.sgml
doc/src/sgml/ref/create_table.sgml
doc/src/sgml/storage.sgml

index 13bd819eb1d63ec3f5af65fbc9f2f7522100752d..4697800ba25e233adbf28aab41b0a49f76d15db2 100644 (file)
     HOT
     
      
-      
-      url="https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/backend/access/heap/README.HOT;hb=HEAD">Heap-Only
-      Tuples
+      Heap-Only Tuples
      
     
    
index 8d6eb75481abaa83335bbd89216726a31267c686..03ea7bbe72956c5809e8b17ef1af263545b982d3 100644 (file)
@@ -708,8 +708,9 @@ options(relopts local_relopts *) returns
    entry.  Version duplicates may sometimes accumulate
    and adversely affect query latency and throughput.  This typically
    occurs with UPDATE-heavy workloads where most
-   individual updates cannot apply the HOT
-   optimization (often because at least one indexed column gets
+   individual updates cannot apply the
+   HOT optimization
+   (often because at least one indexed column gets
    modified, necessitating a new set of index tuple versions —
    one new tuple for each and every index).  In
    effect, B-Tree deduplication ameliorates index bloat caused by
index 5b0c19289995c776df239b30d82f505c99b28132..ebb5a4f3ffd43ec2f55fbc21dfd828a8ef643159 100644 (file)
@@ -4287,7 +4287,7 @@ SCRAM-SHA-256$<iteration count>:&l
       
        If true, queries must not use the index until the xmin
        of this pg_index row is below their TransactionXmin
-       event horizon, because the table may contain broken HOT chains with
+       event horizon, because the table may contain broken HOT chains with
        incompatible rows that they can see
       
      
index 8bce230da00d9f331f289576671b13912c8f2ce9..be67ff7cedfedf0953e103b03e2b2c9ff48d160e 100644 (file)
@@ -4195,7 +4195,8 @@ ANY num_sync ( 
       
        
         Specifies the number of transactions by which VACUUM and
-        HOT updates will defer cleanup of dead row versions. The
+        HOT updates
+        will defer cleanup of dead row versions. The
         default is zero transactions, meaning that dead row versions can be
         removed as soon as possible, that is, as soon as they are no longer
         visible to any open transaction.  You may wish to set this to a
index 6d489bff83286eccb900e74795c6ff3be515a5f8..50d491be8c066f197a2f72faaf5e876c9602b1f7 100644 (file)
@@ -45,7 +45,8 @@
    extant versions of the same logical row; to an index, each tuple is
    an independent object that needs its own index entry.  Thus, an
    update of a row always creates all-new index entries for the row, even if
-   the key values did not change.  (HOT tuples are an exception to this
+   the key values did not change.  (HOT
+   tuples are an exception to this
    statement; but indexes do not deal with those, either.)  Index entries for
    dead tuples are reclaimed (by vacuuming) when the dead tuples themselves
    are reclaimed.
index 0eeed4676a907945cc4b770692c66171080bde89..2ef93680aca391d0469f984fff24df10b7fa88df 100644 (file)
@@ -103,7 +103,9 @@ CREATE INDEX test1_id_index ON test1 (id);
 
   
    After an index is created, the system has to keep it synchronized with the
-   table.  This adds overhead to data manipulation operations.
+   table.  This adds overhead to data manipulation operations.  Indexes can
+   also prevent the creation of heap-only
+   tuples.
    Therefore indexes that are seldom or never used in queries
    should be removed.
   
@@ -733,7 +735,7 @@ CREATE INDEX people_names ON people ((first_name || ' ' || last_name));
   
    Index expressions are relatively expensive to maintain, because the
    derived expression(s) must be computed for each row insertion
-   and non-HOT update.  However, the index expressions are
+   and non-HOT update.  However, the index expressions are
    not recomputed during an indexed search, since they are
    already stored in the index.  In both examples above, the system
    sees the query as just WHERE indexedcolumn = 'constant'
index 6b0ff5ff4c0bd9826e4e7686f033ab7d3ace4bb7..93a84fe28b8ef1ebc999fb3c922f706218d46c82 100644 (file)
@@ -3721,7 +3721,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i
        n_tup_upd bigint
       
       
-       Number of rows updated (includes HOT updated rows)
+       Number of rows updated (includes HOT updated rows)
       
      
 
index 00ce6891171f405a60a9cbeb149d85f336c6a378..1a37922b3a468ee7b65eeea4e58acf45cde64220 100644 (file)
@@ -1357,7 +1357,9 @@ WITH ( MODULUS numeric_literal, REM
       to the indicated percentage; the remaining space on each page is
       reserved for updating rows on that page.  This gives UPDATE
       a chance to place the updated copy of a row on the same page as the
-      original, which is more efficient than placing it on a different page.
+      original, which is more efficient than placing it on a different
+      page, and makes heap-only tuple
+      updates more likely.
       For a table whose entries are never updated, complete packing is the
       best choice, but in heavily updated tables smaller fillfactors are
       appropriate.  This parameter cannot be set for TOAST tables.
index 3234adb639f58b3a4edb00b0e6d58018795b2e5f..cc20d1ca9dd58a7868b6b08ce215cb9f9507f793 100644 (file)
@@ -1070,4 +1070,74 @@ data. Empty in ordinary tables.
  
 
 
+
+
Heap-Only Tuples (<acronym>HOT</acronym>)
+
+  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.
+
+  To help reduce the overhead of updates,
+  PostgreSQL has an optimization called
+  heap-only tuples (HOT).  This optimization is
+  possible when:
+
+  
+   
+    
+     The update does not modify any columns referenced by the table's
+     indexes, including expression and partial indexes.
+     
+   
+   
+    
+     There is sufficient free space on the page containing the old row
+     for the updated row.
+    
+   
+  
+
+  In such cases, heap-only tuples provide two optimizations:
+
+  
+   
+    
+     New index entries are not needed to represent updated rows.
+    
+   
+   
+    
+     Old versions of updated rows can be completely removed during normal
+     operation, including SELECTs, instead of requiring
+     periodic vacuum operations.  (This is possible because indexes
+     do not reference their page
+     item identifiers.)
+    
+   
+  
+
+  In summary, heap-only tuple updates can only be created
+  if columns used by indexes are not updated.  You can
+  increase the likelihood of sufficient page space for
+  HOT updates by decreasing a table's 
+  linkend="sql-createtable">fillfactor.
+  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 
+  linkend="monitoring-pg-stat-all-tables-view">pg_stat_all_tables
+  allows monitoring of the occurrence of HOT and non-HOT updates.
+
+