Optimize RelationFindReplTupleSeq() for CLOBBER_CACHE_ALWAYS.
Specifically, remember lookup_type_cache() results instead of retrieving them once per comparison. Under CLOBBER_CACHE_ALWAYS, this reduced src/test/subscription/t/001_rep_changes.pl elapsed time by an order of magnitude, which reduced check-world elapsed time by 9%. Discussion: https://postgr.es/m/20200406085420.GC162712@rfd.leadboat.com
This commit is contained in:
parent
4216858122
commit
328c70997b
|
@ -225,7 +225,8 @@ retry:
|
||||||
* Compare the tuples in the slots by checking if they have equal values.
|
* Compare the tuples in the slots by checking if they have equal values.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
tuples_equal(TupleTableSlot *slot1, TupleTableSlot *slot2)
|
tuples_equal(TupleTableSlot *slot1, TupleTableSlot *slot2,
|
||||||
|
TypeCacheEntry **eq)
|
||||||
{
|
{
|
||||||
int attrnum;
|
int attrnum;
|
||||||
|
|
||||||
|
@ -256,12 +257,18 @@ tuples_equal(TupleTableSlot *slot1, TupleTableSlot *slot2)
|
||||||
|
|
||||||
att = TupleDescAttr(slot1->tts_tupleDescriptor, attrnum);
|
att = TupleDescAttr(slot1->tts_tupleDescriptor, attrnum);
|
||||||
|
|
||||||
typentry = lookup_type_cache(att->atttypid, TYPECACHE_EQ_OPR_FINFO);
|
typentry = eq[attrnum];
|
||||||
if (!OidIsValid(typentry->eq_opr_finfo.fn_oid))
|
if (typentry == NULL)
|
||||||
ereport(ERROR,
|
{
|
||||||
(errcode(ERRCODE_UNDEFINED_FUNCTION),
|
typentry = lookup_type_cache(att->atttypid,
|
||||||
errmsg("could not identify an equality operator for type %s",
|
TYPECACHE_EQ_OPR_FINFO);
|
||||||
format_type_be(att->atttypid))));
|
if (!OidIsValid(typentry->eq_opr_finfo.fn_oid))
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_UNDEFINED_FUNCTION),
|
||||||
|
errmsg("could not identify an equality operator for type %s",
|
||||||
|
format_type_be(att->atttypid))));
|
||||||
|
eq[attrnum] = typentry;
|
||||||
|
}
|
||||||
|
|
||||||
if (!DatumGetBool(FunctionCall2Coll(&typentry->eq_opr_finfo,
|
if (!DatumGetBool(FunctionCall2Coll(&typentry->eq_opr_finfo,
|
||||||
att->attcollation,
|
att->attcollation,
|
||||||
|
@ -290,12 +297,15 @@ RelationFindReplTupleSeq(Relation rel, LockTupleMode lockmode,
|
||||||
TupleTableSlot *scanslot;
|
TupleTableSlot *scanslot;
|
||||||
TableScanDesc scan;
|
TableScanDesc scan;
|
||||||
SnapshotData snap;
|
SnapshotData snap;
|
||||||
|
TypeCacheEntry **eq;
|
||||||
TransactionId xwait;
|
TransactionId xwait;
|
||||||
bool found;
|
bool found;
|
||||||
TupleDesc desc PG_USED_FOR_ASSERTS_ONLY = RelationGetDescr(rel);
|
TupleDesc desc PG_USED_FOR_ASSERTS_ONLY = RelationGetDescr(rel);
|
||||||
|
|
||||||
Assert(equalTupleDescs(desc, outslot->tts_tupleDescriptor));
|
Assert(equalTupleDescs(desc, outslot->tts_tupleDescriptor));
|
||||||
|
|
||||||
|
eq = palloc0(sizeof(*eq) * outslot->tts_tupleDescriptor->natts);
|
||||||
|
|
||||||
/* Start a heap scan. */
|
/* Start a heap scan. */
|
||||||
InitDirtySnapshot(snap);
|
InitDirtySnapshot(snap);
|
||||||
scan = table_beginscan(rel, &snap, 0, NULL);
|
scan = table_beginscan(rel, &snap, 0, NULL);
|
||||||
|
@ -309,7 +319,7 @@ retry:
|
||||||
/* Try to find the tuple */
|
/* Try to find the tuple */
|
||||||
while (table_scan_getnextslot(scan, ForwardScanDirection, scanslot))
|
while (table_scan_getnextslot(scan, ForwardScanDirection, scanslot))
|
||||||
{
|
{
|
||||||
if (!tuples_equal(scanslot, searchslot))
|
if (!tuples_equal(scanslot, searchslot, eq))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
found = true;
|
found = true;
|
||||||
|
|
Loading…
Reference in New Issue