aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor
diff options
context:
space:
mode:
authorTomas Vondra <tomas.vondra@postgresql.org>2023-03-20 10:34:07 +0100
committerTomas Vondra <tomas.vondra@postgresql.org>2023-03-20 11:02:42 +0100
commit19d8e2308bc51ec4ab993ce90077342c915dd116 (patch)
tree80742287fd696662b892802b6ced26e93e7d68fb /src/backend/executor
parente8583126833a53f4eebe28a8de45d128f01ff664 (diff)
downloadpostgresql-19d8e2308bc51ec4ab993ce90077342c915dd116.tar.gz
postgresql-19d8e2308bc51ec4ab993ce90077342c915dd116.zip
Ignore BRIN indexes when checking for HOT updates
When determining whether an index update may be skipped by using HOT, we can ignore attributes indexed by block summarizing indexes without references to individual tuples that need to be cleaned up. A new type TU_UpdateIndexes provides a signal to the executor to determine which indexes to update - no indexes, all indexes, or only the summarizing indexes. This also removes rd_indexattr list, and replaces it with rd_attrsvalid flag. The list was not used anywhere, and a simple flag is sufficient. This was originally committed as 5753d4ee32, but then got reverted by e3fcca0d0d because of correctness issues. Original patch by Josef Simanek, various fixes and improvements by Tomas Vondra and me. Authors: Matthias van de Meent, Josef Simanek, Tomas Vondra Reviewed-by: Tomas Vondra, Alvaro Herrera Discussion: https://postgr.es/m/05ebcb44-f383-86e3-4f31-0a97a55634cf@enterprisedb.com Discussion: https://postgr.es/m/CAFp7QwpMRGcDAQumN7onN9HjrJ3u4X3ZRXdGFT0K5G2JWvnbWg%40mail.gmail.com
Diffstat (limited to 'src/backend/executor')
-rw-r--r--src/backend/executor/execIndexing.c37
-rw-r--r--src/backend/executor/execReplication.c9
-rw-r--r--src/backend/executor/nodeModifyTable.c13
3 files changed, 40 insertions, 19 deletions
diff --git a/src/backend/executor/execIndexing.c b/src/backend/executor/execIndexing.c
index 6e88e72813f..da28e5e40ca 100644
--- a/src/backend/executor/execIndexing.c
+++ b/src/backend/executor/execIndexing.c
@@ -259,15 +259,24 @@ ExecCloseIndices(ResultRelInfo *resultRelInfo)
* into all the relations indexing the result relation
* when a heap tuple is inserted into the result relation.
*
- * When 'update' is true, executor is performing an UPDATE
- * that could not use an optimization like heapam's HOT (in
- * more general terms a call to table_tuple_update() took
- * place and set 'update_indexes' to true). Receiving this
- * hint makes us consider if we should pass down the
- * 'indexUnchanged' hint in turn. That's something that we
- * figure out for each index_insert() call iff 'update' is
- * true. (When 'update' is false we already know not to pass
- * the hint to any index.)
+ * When 'update' is true and 'onlySummarizing' is false,
+ * executor is performing an UPDATE that could not use an
+ * optimization like heapam's HOT (in more general terms a
+ * call to table_tuple_update() took place and set
+ * 'update_indexes' to TUUI_All). Receiving this hint makes
+ * us consider if we should pass down the 'indexUnchanged'
+ * hint in turn. That's something that we figure out for
+ * each index_insert() call iff 'update' is true.
+ * (When 'update' is false we already know not to pass the
+ * hint to any index.)
+ *
+ * If onlySummarizing is set, an equivalent optimization to
+ * HOT has been applied and any updated columns are indexed
+ * only by summarizing indexes (or in more general terms a
+ * call to table_tuple_update() took place and set
+ * 'update_indexes' to TUUI_Summarizing). We can (and must)
+ * therefore only update the indexes that have
+ * 'amsummarizing' = true.
*
* Unique and exclusion constraints are enforced at the same
* time. This returns a list of index OIDs for any unique or
@@ -287,7 +296,8 @@ ExecInsertIndexTuples(ResultRelInfo *resultRelInfo,
bool update,
bool noDupErr,
bool *specConflict,
- List *arbiterIndexes)
+ List *arbiterIndexes,
+ bool onlySummarizing)
{
ItemPointer tupleid = &slot->tts_tid;
List *result = NIL;
@@ -343,6 +353,13 @@ ExecInsertIndexTuples(ResultRelInfo *resultRelInfo,
if (!indexInfo->ii_ReadyForInserts)
continue;
+ /*
+ * Skip processing of non-summarizing indexes if we only
+ * update summarizing indexes
+ */
+ if (onlySummarizing && !indexInfo->ii_Summarizing)
+ continue;
+
/* Check for partial index */
if (indexInfo->ii_Predicate != NIL)
{
diff --git a/src/backend/executor/execReplication.c b/src/backend/executor/execReplication.c
index fa8628e3e1b..c4bc69f1e55 100644
--- a/src/backend/executor/execReplication.c
+++ b/src/backend/executor/execReplication.c
@@ -491,7 +491,7 @@ ExecSimpleRelationInsert(ResultRelInfo *resultRelInfo,
if (resultRelInfo->ri_NumIndices > 0)
recheckIndexes = ExecInsertIndexTuples(resultRelInfo,
slot, estate, false, false,
- NULL, NIL);
+ NULL, NIL, false);
/* AFTER ROW INSERT Triggers */
ExecARInsertTriggers(estate, resultRelInfo, slot,
@@ -539,7 +539,7 @@ ExecSimpleRelationUpdate(ResultRelInfo *resultRelInfo,
if (!skip_tuple)
{
List *recheckIndexes = NIL;
- bool update_indexes;
+ TU_UpdateIndexes update_indexes;
/* Compute stored generated columns */
if (rel->rd_att->constr &&
@@ -556,10 +556,11 @@ ExecSimpleRelationUpdate(ResultRelInfo *resultRelInfo,
simple_table_tuple_update(rel, tid, slot, estate->es_snapshot,
&update_indexes);
- if (resultRelInfo->ri_NumIndices > 0 && update_indexes)
+ if (resultRelInfo->ri_NumIndices > 0 && (update_indexes != TU_None))
recheckIndexes = ExecInsertIndexTuples(resultRelInfo,
slot, estate, true, false,
- NULL, NIL);
+ NULL, NIL,
+ (update_indexes == TU_Summarizing));
/* AFTER ROW UPDATE Triggers */
ExecARUpdateTriggers(estate, resultRelInfo,
diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c
index 3fa2b930a52..3a673895082 100644
--- a/src/backend/executor/nodeModifyTable.c
+++ b/src/backend/executor/nodeModifyTable.c
@@ -110,8 +110,8 @@ typedef struct ModifyTableContext
typedef struct UpdateContext
{
bool updated; /* did UPDATE actually occur? */
- bool updateIndexes; /* index update required? */
bool crossPartUpdate; /* was it a cross-partition update? */
+ TU_UpdateIndexes updateIndexes; /* Which index updates are required? */
/*
* Lock mode to acquire on the latest tuple version before performing
@@ -1099,7 +1099,8 @@ ExecInsert(ModifyTableContext *context,
recheckIndexes = ExecInsertIndexTuples(resultRelInfo,
slot, estate, false, true,
&specConflict,
- arbiterIndexes);
+ arbiterIndexes,
+ false);
/* adjust the tuple's state accordingly */
table_tuple_complete_speculative(resultRelationDesc, slot,
@@ -1138,7 +1139,8 @@ ExecInsert(ModifyTableContext *context,
if (resultRelInfo->ri_NumIndices > 0)
recheckIndexes = ExecInsertIndexTuples(resultRelInfo,
slot, estate, false,
- false, NULL, NIL);
+ false, NULL, NIL,
+ false);
}
}
@@ -2118,11 +2120,12 @@ ExecUpdateEpilogue(ModifyTableContext *context, UpdateContext *updateCxt,
List *recheckIndexes = NIL;
/* insert index entries for tuple if necessary */
- if (resultRelInfo->ri_NumIndices > 0 && updateCxt->updateIndexes)
+ if (resultRelInfo->ri_NumIndices > 0 && (updateCxt->updateIndexes != TU_None))
recheckIndexes = ExecInsertIndexTuples(resultRelInfo,
slot, context->estate,
true, false,
- NULL, NIL);
+ NULL, NIL,
+ (updateCxt->updateIndexes == TU_Summarizing));
/* AFTER ROW UPDATE Triggers */
ExecARUpdateTriggers(context->estate, resultRelInfo,