1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-28 23:42:10 +03:00

Allow HOT updates for some expression indexes

If the value of an index expression is unchanged after UPDATE,
allow HOT updates where previously we disallowed them, giving
a significant performance boost in those cases.

Particularly useful for indexes such as JSON->>field where the
JSON value changes but the indexed value does not.

Submitted as "surjective indexes" patch, now enabled by use
of new "recheck_on_update" parameter.

Author: Konstantin Knizhnik
Reviewer: Simon Riggs, with much wordsmithing and some cleanup
This commit is contained in:
Simon Riggs
2018-03-27 19:57:02 +01:00
parent 1944cdc982
commit c203d6cf81
13 changed files with 395 additions and 22 deletions

View File

@ -129,6 +129,15 @@ static relopt_bool boolRelOpts[] =
},
true
},
{
{
"recheck_on_update",
"Recheck functional index expression for changed value after update",
RELOPT_KIND_INDEX,
ShareUpdateExclusiveLock /* since only applies to later UPDATEs */
},
true
},
{
{
"security_barrier",
@ -1310,7 +1319,7 @@ fillRelOptions(void *rdopts, Size basesize,
break;
}
}
if (validate && !found)
if (validate && !found && options[i].gen->kinds != RELOPT_KIND_INDEX)
elog(ERROR, "reloption \"%s\" not found in parse table",
options[i].gen->name);
}
@ -1466,6 +1475,40 @@ index_reloptions(amoptions_function amoptions, Datum reloptions, bool validate)
return amoptions(reloptions, validate);
}
/*
* Parse generic options for all indexes.
*
* reloptions options as text[] datum
* validate error flag
*/
bytea *
index_generic_reloptions(Datum reloptions, bool validate)
{
int numoptions;
GenericIndexOpts *idxopts;
relopt_value *options;
static const relopt_parse_elt tab[] = {
{"recheck_on_update", RELOPT_TYPE_BOOL, offsetof(GenericIndexOpts, recheck_on_update)}
};
options = parseRelOptions(reloptions, validate,
RELOPT_KIND_INDEX,
&numoptions);
/* if none set, we're done */
if (numoptions == 0)
return NULL;
idxopts = allocateReloptStruct(sizeof(GenericIndexOpts), options, numoptions);
fillRelOptions((void *)idxopts, sizeof(GenericIndexOpts), options, numoptions,
validate, tab, lengthof(tab));
pfree(options);
return (bytea*) idxopts;
}
/*
* Option parser for attribute reloptions
*/