From: Bruce Momjian <bruce@momjian.us>
To: Chris Lowder <clowder@hey.com>
Cc: pgsql-docs@lists.postgresql.org
Subject: Re: 11.7. Indexes on Expressions
Date: Fri, 17 Dec 2021 16:43:43 -0500
Message-ID: <20211217214343.GC5592@momjian.us> (raw)
In-Reply-To: <b4093b5a1383fe157e7dfd52606f4173352fd4fb@hey.com>
References: <20211216205232.GA30462@momjian.us>
<b4093b5a1383fe157e7dfd52606f4173352fd4fb@hey.com>
On Fri, Dec 17, 2021 at 09:41:32AM +0000, Chris Lowder wrote:
> Thank you for that (speedy) explanation and patch Bruce! That all makes perfect
> sense.
There are actually two questions being addressed here:
1. In what cases are new index entries added, and for which indexes?
2. In what cases are index expressions evaluated?
For 1, I explained that for updates we either add new rows for all
indexes, or none of them. We create new index rows for non-HOT updates,
which happens if the updated row does not change indexed columns (or
columns involved in index expressions), and if the new row fits on the
same 8k heap page.
What I recently learned, at least for PG 10-14, is that the index
expression is only called for non-HOT updates, not HOT ones. Postgres
does not evaluate the index expression to determine if the indexed
expression has changed, but rather relies on column value comparisons.
I wrote the attached script which creates an expression index function
with a pg_sleep(1) call to determine if the function is called. If you
run the attached SQL script in psql, you will see that times of ~1
second happens only when there is a change in the colummn referenced by
the index expression or when the new row is stored on a new heap page
(ctid page number changes). The expression index function is not called
if the indexed column value does not change and remains on the same heap
page.
I am attaching an updated patch which mentions non-HOT updates for
expression indexes.
--
Bruce Momjian <bruce@momjian.us> https://momjian.us
EDB https://enterprisedb.com
If only the physical world exists, free will is an illusion.
Attachments:
[application/x-sql] expr.sql (1.9K, ../20211217214343.GC5592@momjian.us/2-expr.sql)
download
[text/x-diff] expression.diff (836B, ../20211217214343.GC5592@momjian.us/3-expression.diff)
download | inline diff:diff --git a/doc/src/sgml/indices.sgml b/doc/src/sgml/indices.sgmlindex 56fbd45178..023157d888 100644--- a/doc/src/sgml/indices.sgml+++ b/doc/src/sgml/indices.sgml@@ -748,8 +748,8 @@ CREATE INDEX people_names ON people ((first_name || ' ' || last_name));
<para>
Index expressions are relatively expensive to maintain, because the
- derived expression(s) must be computed for each row upon insertion- and whenever it is updated. However, the index expressions are+ derived expression(s) must be computed for each row insertion+ and non-HOT update. However, the index expressions are
<emphasis>not</emphasis> recomputed during an indexed search, since they are
already stored in the index. In both examples above, the system
sees the query as just <literal>WHERE indexedcolumn = 'constant'</literal>
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-docs@postgresql.org
Cc: bruce@momjian.us, clowder@hey.com, pgsql-docs@lists.postgresql.org
Subject: Re: 11.7. Indexes on Expressions
In-Reply-To: <20211217214343.GC5592@momjian.us>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox