Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 63c833f

Browse files
committed
Use multi-inserts for pg_ts_config_map
Two locations working on pg_ts_config_map are switched from CatalogTupleInsert() to a multi-insert approach with tuple slots: - ALTER TEXT SEARCH CONFIGURATION ADD/ALTER MAPPING when inserting new entries. The number of entries to insert is known in advance, so is the number of slots needed. Note that CatalogTupleInsertWithInfo() is now used for the entry updates. - CREATE TEXT SEARCH CONFIGURATION, where up to ~20-ish records could be inserted at once. The number of slots is not known in advance, hence a slot initialization is delayed until a tuple is stored in it. Like all the changes of this kind (1ff4161, 63110c6 or e3931d0), an insert batch is capped at 64kB. Author: Michael Paquier, Ranier Vilela Reviewed-by: Kyotaro Horiguchi Discussion: https://postgr.es/m/Y3M5bovrkTQbAO4W@paquier.xyz
1 parent 36e0358 commit 63c833f

File tree

1 file changed

+97
-23
lines changed

1 file changed

+97
-23
lines changed

src/backend/commands/tsearchcmds.c

+97-23
Original file line numberDiff line numberDiff line change
@@ -1004,8 +1004,24 @@ DefineTSConfiguration(List *names, List *parameters, ObjectAddress *copied)
10041004
ScanKeyData skey;
10051005
SysScanDesc scan;
10061006
HeapTuple maptup;
1007+
TupleDesc mapDesc;
1008+
TupleTableSlot **slot;
1009+
CatalogIndexState indstate;
1010+
int max_slots,
1011+
slot_init_count,
1012+
slot_stored_count;
10071013

10081014
mapRel = table_open(TSConfigMapRelationId, RowExclusiveLock);
1015+
mapDesc = RelationGetDescr(mapRel);
1016+
1017+
indstate = CatalogOpenIndexes(mapRel);
1018+
1019+
/*
1020+
* Allocate the slots to use, but delay costly initialization until we
1021+
* know that they will be used.
1022+
*/
1023+
max_slots = MAX_CATALOG_MULTI_INSERT_BYTES / sizeof(FormData_pg_ts_config_map);
1024+
slot = palloc(sizeof(TupleTableSlot *) * max_slots);
10091025

10101026
ScanKeyInit(&skey,
10111027
Anum_pg_ts_config_map_mapcfg,
@@ -1015,29 +1031,54 @@ DefineTSConfiguration(List *names, List *parameters, ObjectAddress *copied)
10151031
scan = systable_beginscan(mapRel, TSConfigMapIndexId, true,
10161032
NULL, 1, &skey);
10171033

1034+
/* number of slots currently storing tuples */
1035+
slot_stored_count = 0;
1036+
/* number of slots currently initialized */
1037+
slot_init_count = 0;
1038+
10181039
while (HeapTupleIsValid((maptup = systable_getnext(scan))))
10191040
{
10201041
Form_pg_ts_config_map cfgmap = (Form_pg_ts_config_map) GETSTRUCT(maptup);
1021-
HeapTuple newmaptup;
1022-
Datum mapvalues[Natts_pg_ts_config_map];
1023-
bool mapnulls[Natts_pg_ts_config_map];
10241042

1025-
memset(mapvalues, 0, sizeof(mapvalues));
1026-
memset(mapnulls, false, sizeof(mapnulls));
1043+
if (slot_init_count < max_slots)
1044+
{
1045+
slot[slot_stored_count] = MakeSingleTupleTableSlot(mapDesc,
1046+
&TTSOpsHeapTuple);
1047+
slot_init_count++;
1048+
}
1049+
1050+
ExecClearTuple(slot[slot_stored_count]);
10271051

1028-
mapvalues[Anum_pg_ts_config_map_mapcfg - 1] = cfgOid;
1029-
mapvalues[Anum_pg_ts_config_map_maptokentype - 1] = cfgmap->maptokentype;
1030-
mapvalues[Anum_pg_ts_config_map_mapseqno - 1] = cfgmap->mapseqno;
1031-
mapvalues[Anum_pg_ts_config_map_mapdict - 1] = cfgmap->mapdict;
1052+
memset(slot[slot_stored_count]->tts_isnull, false,
1053+
slot[slot_stored_count]->tts_tupleDescriptor->natts * sizeof(bool));
10321054

1033-
newmaptup = heap_form_tuple(mapRel->rd_att, mapvalues, mapnulls);
1055+
slot[slot_stored_count]->tts_values[Anum_pg_ts_config_map_mapcfg - 1] = cfgOid;
1056+
slot[slot_stored_count]->tts_values[Anum_pg_ts_config_map_maptokentype - 1] = cfgmap->maptokentype;
1057+
slot[slot_stored_count]->tts_values[Anum_pg_ts_config_map_mapseqno - 1] = cfgmap->mapseqno;
1058+
slot[slot_stored_count]->tts_values[Anum_pg_ts_config_map_mapdict - 1] = cfgmap->mapdict;
10341059

1035-
CatalogTupleInsert(mapRel, newmaptup);
1060+
ExecStoreVirtualTuple(slot[slot_stored_count]);
1061+
slot_stored_count++;
10361062

1037-
heap_freetuple(newmaptup);
1063+
/* If slots are full, insert a batch of tuples */
1064+
if (slot_stored_count == max_slots)
1065+
{
1066+
CatalogTuplesMultiInsertWithInfo(mapRel, slot, slot_stored_count,
1067+
indstate);
1068+
slot_stored_count = 0;
1069+
}
10381070
}
10391071

1072+
/* Insert any tuples left in the buffer */
1073+
if (slot_stored_count > 0)
1074+
CatalogTuplesMultiInsertWithInfo(mapRel, slot, slot_stored_count,
1075+
indstate);
1076+
1077+
for (int i = 0; i < slot_init_count; i++)
1078+
ExecDropSingleTupleTableSlot(slot[i]);
1079+
10401080
systable_endscan(scan);
1081+
CatalogCloseIndexes(indstate);
10411082
}
10421083

10431084
address = makeConfigurationDependencies(tup, false, mapRel);
@@ -1225,6 +1266,7 @@ MakeConfigurationMapping(AlterTSConfigurationStmt *stmt,
12251266
Oid *dictIds;
12261267
int ndict;
12271268
ListCell *c;
1269+
CatalogIndexState indstate;
12281270

12291271
tsform = (Form_pg_ts_config) GETSTRUCT(tup);
12301272
cfgId = tsform->oid;
@@ -1275,6 +1317,8 @@ MakeConfigurationMapping(AlterTSConfigurationStmt *stmt,
12751317
i++;
12761318
}
12771319

1320+
indstate = CatalogOpenIndexes(relMap);
1321+
12781322
if (stmt->replace)
12791323
{
12801324
/*
@@ -1334,38 +1378,68 @@ MakeConfigurationMapping(AlterTSConfigurationStmt *stmt,
13341378
newtup = heap_modify_tuple(maptup,
13351379
RelationGetDescr(relMap),
13361380
repl_val, repl_null, repl_repl);
1337-
CatalogTupleUpdate(relMap, &newtup->t_self, newtup);
1381+
CatalogTupleUpdateWithInfo(relMap, &newtup->t_self, newtup, indstate);
13381382
}
13391383
}
13401384

13411385
systable_endscan(scan);
13421386
}
13431387
else
13441388
{
1389+
TupleTableSlot **slot;
1390+
int slotCount = 0;
1391+
int nslots;
1392+
1393+
/* Allocate the slots to use and initialize them */
1394+
nslots = Min(ntoken * ndict,
1395+
MAX_CATALOG_MULTI_INSERT_BYTES / sizeof(FormData_pg_ts_config_map));
1396+
slot = palloc(sizeof(TupleTableSlot *) * nslots);
1397+
for (i = 0; i < nslots; i++)
1398+
slot[i] = MakeSingleTupleTableSlot(RelationGetDescr(relMap),
1399+
&TTSOpsHeapTuple);
1400+
13451401
/*
13461402
* Insertion of new entries
13471403
*/
13481404
for (i = 0; i < ntoken; i++)
13491405
{
13501406
for (j = 0; j < ndict; j++)
13511407
{
1352-
Datum values[Natts_pg_ts_config_map];
1353-
bool nulls[Natts_pg_ts_config_map];
1408+
ExecClearTuple(slot[slotCount]);
1409+
1410+
memset(slot[slotCount]->tts_isnull, false,
1411+
slot[slotCount]->tts_tupleDescriptor->natts * sizeof(bool));
13541412

1355-
memset(nulls, false, sizeof(nulls));
1356-
values[Anum_pg_ts_config_map_mapcfg - 1] = ObjectIdGetDatum(cfgId);
1357-
values[Anum_pg_ts_config_map_maptokentype - 1] = Int32GetDatum(tokens[i]);
1358-
values[Anum_pg_ts_config_map_mapseqno - 1] = Int32GetDatum(j + 1);
1359-
values[Anum_pg_ts_config_map_mapdict - 1] = ObjectIdGetDatum(dictIds[j]);
1413+
slot[slotCount]->tts_values[Anum_pg_ts_config_map_mapcfg - 1] = ObjectIdGetDatum(cfgId);
1414+
slot[slotCount]->tts_values[Anum_pg_ts_config_map_maptokentype - 1] = Int32GetDatum(tokens[i]);
1415+
slot[slotCount]->tts_values[Anum_pg_ts_config_map_mapseqno - 1] = Int32GetDatum(j + 1);
1416+
slot[slotCount]->tts_values[Anum_pg_ts_config_map_mapdict - 1] = ObjectIdGetDatum(dictIds[j]);
13601417

1361-
tup = heap_form_tuple(relMap->rd_att, values, nulls);
1362-
CatalogTupleInsert(relMap, tup);
1418+
ExecStoreVirtualTuple(slot[slotCount]);
1419+
slotCount++;
13631420

1364-
heap_freetuple(tup);
1421+
/* If slots are full, insert a batch of tuples */
1422+
if (slotCount == nslots)
1423+
{
1424+
CatalogTuplesMultiInsertWithInfo(relMap, slot, slotCount,
1425+
indstate);
1426+
slotCount = 0;
1427+
}
13651428
}
13661429
}
1430+
1431+
/* Insert any tuples left in the buffer */
1432+
if (slotCount > 0)
1433+
CatalogTuplesMultiInsertWithInfo(relMap, slot, slotCount,
1434+
indstate);
1435+
1436+
for (i = 0; i < nslots; i++)
1437+
ExecDropSingleTupleTableSlot(slot[i]);
13671438
}
13681439

1440+
/* clean up */
1441+
CatalogCloseIndexes(indstate);
1442+
13691443
EventTriggerCollectAlterTSConfig(stmt, cfgId, dictIds, ndict);
13701444
}
13711445

0 commit comments

Comments
 (0)