Hi,
The commit
https://github.com/postgres/postgres/commit/b17ff07aa3eb142d2cde2ea00e4a4e8f63686f96
Introduced the CopyStatistics function.
To do the work, CopyStatistics uses a less efficient function
to update/insert tuples at catalog systems.
The comment at indexing.c says:
"Avoid using it for multiple tuples, since opening the indexes
* and building the index info structures is moderately expensive.
* (Use CatalogTupleInsertWithInfo in such cases.)"
So inspired by the comment, changed in some fews places,
the CatalogInsert/CatalogUpdate to more efficient functions
CatalogInsertWithInfo/CatalogUpdateWithInfo.
With quick tests, resulting in small performance.
head:
1. REINDEX TABLE CONCURRENTLY pgbench_accounts;
Time: 77,805 ms
Time: 74,836 ms
Time: 73,480 ms
2. REINDEX TABLE CONCURRENTLY pgbench_tellers;
Time: 22,260 ms
Time: 22,205 ms
Time: 21,008 ms
patched:
1. REINDEX TABLE CONCURRENTLY pgbench_accounts;
Time: 65,048 ms
Time: 61,853 ms
Time: 61,119 ms
2. REINDEX TABLE CONCURRENTLY pgbench_tellers;
Time: 15,999 ms
Time: 15,961 ms
Time: 13,264 ms
There are other places that this could be useful,
but a careful analysis is necessary.
regards,
Ranier Vilela
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 9b03579e6e..cf15051a05 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -2856,8 +2856,7 @@ CopyStatistics(Oid fromrelid, Oid torelid)
SysScanDesc scan;
ScanKeyData key[1];
Relation statrel;
-
- statrel = table_open(StatisticRelationId, RowExclusiveLock);
+ CatalogIndexState indstate;
/* Now search for stat records */
ScanKeyInit(&key[0],
@@ -2865,6 +2864,9 @@ CopyStatistics(Oid fromrelid, Oid torelid)
BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(fromrelid));
+ statrel = table_open(StatisticRelationId, RowExclusiveLock);
+ indstate = CatalogOpenIndexes(statrel);
+
scan = systable_beginscan(statrel, StatisticRelidAttnumInhIndexId,
true, NULL, 1, key);
@@ -2878,13 +2880,14 @@ CopyStatistics(Oid fromrelid, Oid torelid)
/* update the copy of the tuple and insert it */
statform->starelid = torelid;
- CatalogTupleInsert(statrel, tup);
+ CatalogTupleInsertWithInfo(statrel, tup, indstate);
heap_freetuple(tup);
}
systable_endscan(scan);
+ CatalogCloseIndexes(indstate);
table_close(statrel, RowExclusiveLock);
}
diff --git a/src/backend/catalog/pg_enum.c b/src/backend/catalog/pg_enum.c
index 114715498d..785fbc1669 100644
--- a/src/backend/catalog/pg_enum.c
+++ b/src/backend/catalog/pg_enum.c
@@ -69,6 +69,7 @@ EnumValuesCreate(Oid enumTypeOid, List *vals)
bool nulls[Natts_pg_enum];
ListCell *lc;
HeapTuple tup;
+ CatalogIndexState indstate;
num_elems = list_length(vals);
@@ -113,6 +114,9 @@ EnumValuesCreate(Oid enumTypeOid, List *vals)
/* and make the entries */
memset(nulls, false, sizeof(nulls));
+ /* open the Catalog Indexes for Insert Tuples */
+ indstate = CatalogOpenIndexes(pg_enum);
+
elemno = 0;
foreach(lc, vals)
{
@@ -137,7 +141,7 @@ EnumValuesCreate(Oid enumTypeOid, List *vals)
tup = heap_form_tuple(RelationGetDescr(pg_enum), values, nulls);
- CatalogTupleInsert(pg_enum, tup);
+ CatalogTupleInsertWithInfo(pg_enum, tup, indstate);
heap_freetuple(tup);
elemno++;
@@ -145,6 +149,7 @@ EnumValuesCreate(Oid enumTypeOid, List *vals)
/* clean up */
pfree(oids);
+ CatalogCloseIndexes(indstate);
table_close(pg_enum, RowExclusiveLock);
}
diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c
index a7966fff83..5cfcdf8ba7 100644
--- a/src/backend/commands/analyze.c
+++ b/src/backend/commands/analyze.c
@@ -1624,12 +1624,14 @@ static void
update_attstats(Oid relid, bool inh, int natts, VacAttrStats **vacattrstats)
{
Relation sd;
+ CatalogIndexState indstate;
int attno;
if (natts <= 0)
return; /* nothing to do */
sd = table_open(StatisticRelationId, RowExclusiveLock);
+ indstate = CatalogOpenIndexes(sd);
for (attno = 0; attno < natts; attno++)
{
@@ -1735,18 +1737,19 @@ update_attstats(Oid relid, bool inh, int natts, VacAttrStats **vacattrstats)
nulls,
replaces);
ReleaseSysCache(oldtup);
- CatalogTupleUpdate(sd, &stup->t_self, stup);
+ CatalogTupleUpdateWithInfo(sd, &stup->t_self, stup, indstate);
}
else
{
/* No, insert new tuple */
stup = heap_form_tuple(RelationGetDescr(sd), values, nulls);
- CatalogTupleInsert(sd, stup);
+ CatalogTupleInsertWithInfo(sd, stup, indstate);
}
heap_freetuple(stup);
}
+ CatalogCloseIndexes(indstate);
table_close(sd, RowExclusiveLock);
}
diff --git a/src/backend/commands/tsearchcmds.c b/src/backend/commands/tsearchcmds.c
index 4cc4e3c00f..b95b989c5a 100644
--- a/src/backend/commands/tsearchcmds.c
+++ b/src/backend/commands/tsearchcmds.c
@@ -1004,14 +1004,16 @@ DefineTSConfiguration(List *names, List *parameters, ObjectAddress *copied)
ScanKeyData skey;
SysScanDesc scan;
HeapTuple maptup;
-
- mapRel = table_open(TSConfigMapRelationId, RowExclusiveLock);
+ CatalogIndexState indstate;
ScanKeyInit(&skey,
Anum_pg_ts_config_map_mapcfg,
BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(sourceOid));
+ mapRel = table_open(TSConfigMapRelationId, RowExclusiveLock);
+ indstate = CatalogOpenIndexes(mapRel);
+
scan = systable_beginscan(mapRel, TSConfigMapIndexId, true,
NULL, 1, &skey);
@@ -1032,12 +1034,14 @@ DefineTSConfiguration(List *names, List *parameters, ObjectAddress *copied)
newmaptup = heap_form_tuple(mapRel->rd_att, mapvalues, mapnulls);
- CatalogTupleInsert(mapRel, newmaptup);
+ CatalogTupleInsertWithInfo(mapRel, newmaptup, indstate);
heap_freetuple(newmaptup);
}
systable_endscan(scan);
+
+ CatalogCloseIndexes(indstate);
}
address = makeConfigurationDependencies(tup, false, mapRel);
@@ -1225,6 +1229,7 @@ MakeConfigurationMapping(AlterTSConfigurationStmt *stmt,
Oid *dictIds;
int ndict;
ListCell *c;
+ CatalogIndexState indstate;
tsform = (Form_pg_ts_config) GETSTRUCT(tup);
cfgId = tsform->oid;
@@ -1275,6 +1280,9 @@ MakeConfigurationMapping(AlterTSConfigurationStmt *stmt,
i++;
}
+ /* open the Catalog Indexes for Update/Insert Tuples */
+ indstate = CatalogOpenIndexes(relMap);
+
if (stmt->replace)
{
/*
@@ -1334,7 +1342,7 @@ MakeConfigurationMapping(AlterTSConfigurationStmt *stmt,
newtup = heap_modify_tuple(maptup,
RelationGetDescr(relMap),
repl_val, repl_null, repl_repl);
- CatalogTupleUpdate(relMap, &newtup->t_self, newtup);
+ CatalogTupleUpdateWithInfo(relMap, &newtup->t_self, newtup, indstate);
}
}
@@ -1359,12 +1367,13 @@ MakeConfigurationMapping(AlterTSConfigurationStmt *stmt,
values[Anum_pg_ts_config_map_mapdict - 1] = ObjectIdGetDatum(dictIds[j]);
tup = heap_form_tuple(relMap->rd_att, values, nulls);
- CatalogTupleInsert(relMap, tup);
+ CatalogTupleInsertWithInfo(relMap, tup, indstate);
heap_freetuple(tup);
}
}
}
+ CatalogCloseIndexes(indstate);
EventTriggerCollectAlterTSConfig(stmt, cfgId, dictIds, ndict);
}
diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c
index 265a48af7e..f9521bc1dd 100644
--- a/src/backend/commands/user.c
+++ b/src/backend/commands/user.c
@@ -1551,6 +1551,7 @@ AddRoleMems(const char *rolename, Oid roleid,
{
Relation pg_authmem_rel;
TupleDesc pg_authmem_dsc;
+ CatalogIndexState indstate;
ListCell *specitem;
ListCell *iditem;
Oid currentUserId = GetUserId();
@@ -1718,6 +1719,9 @@ AddRoleMems(const char *rolename, Oid roleid,
ReleaseSysCacheList(memlist);
}
+ /* open the Catalog Indexes for Update/Insert Tuples */
+ indstate = CatalogOpenIndexes(pg_authmem_rel);
+
/* Now perform the catalog updates. */
forboth(specitem, memberSpecs, iditem, memberIds)
{
@@ -1789,7 +1793,7 @@ AddRoleMems(const char *rolename, Oid roleid,
tuple = heap_modify_tuple(authmem_tuple, pg_authmem_dsc,
new_record,
new_record_nulls, new_record_repl);
- CatalogTupleUpdate(pg_authmem_rel, &tuple->t_self, tuple);
+ CatalogTupleUpdateWithInfo(pg_authmem_rel, &tuple->t_self, tuple, indstate);
ReleaseSysCache(authmem_tuple);
}
@@ -1829,7 +1833,7 @@ AddRoleMems(const char *rolename, Oid roleid,
new_record[Anum_pg_auth_members_oid - 1] = objectId;
tuple = heap_form_tuple(pg_authmem_dsc,
new_record, new_record_nulls);
- CatalogTupleInsert(pg_authmem_rel, tuple);
+ CatalogTupleInsertWithInfo(pg_authmem_rel, tuple, indstate);
/* updateAclDependencies wants to pfree array inputs */
newmembers[0] = grantorId;
@@ -1842,6 +1846,7 @@ AddRoleMems(const char *rolename, Oid roleid,
/* CCI after each change, in case there are duplicates in list */
CommandCounterIncrement();
}
+ CatalogCloseIndexes(indstate);
/*
* Close pg_authmem, but keep lock till commit.