Cache the results of format_type() queries in pg_dump.
There's long been a "TODO: there might be some value in caching the results" annotation on pg_dump's getFormattedTypeName function; but we hadn't gotten around to checking what it was costing us to repetitively look up type names. It turns out that when dumping the current regression database, about 10% of the total number of queries issued are duplicative format_type() queries. However, Hubert Depesz Lubaczewski reported a not-unusual case where these account for over half of the queries issued by pg_dump. Individually these queries aren't expensive, but when network lag is a factor, they add up to a problem. We can very easily add some caching to getFormattedTypeName to solve it. Since this is such a simple fix and can have a visible performance benefit, back-patch to all supported branches. Discussion: https://postgr.es/m/20210826084430.GA26282@depesz.com
This commit is contained in:
parent
bce24d1edb
commit
c4b298ee15
@ -4939,6 +4939,7 @@ getTypes(Archive *fout, int *numTypes)
|
||||
tyinfo[i].dobj.namespace =
|
||||
findNamespace(fout,
|
||||
atooid(PQgetvalue(res, i, i_typnamespace)));
|
||||
tyinfo[i].ftypname = NULL; /* may get filled later */
|
||||
tyinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname));
|
||||
tyinfo[i].typacl = pg_strdup(PQgetvalue(res, i, i_typacl));
|
||||
tyinfo[i].rtypacl = pg_strdup(PQgetvalue(res, i, i_rtypacl));
|
||||
@ -18480,12 +18481,11 @@ findDumpableDependencies(ArchiveHandle *AH, DumpableObject *dobj,
|
||||
*
|
||||
* This does not guarantee to schema-qualify the output, so it should not
|
||||
* be used to create the target object name for CREATE or ALTER commands.
|
||||
*
|
||||
* TODO: there might be some value in caching the results.
|
||||
*/
|
||||
static char *
|
||||
getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts)
|
||||
{
|
||||
TypeInfo *typeInfo;
|
||||
char *result;
|
||||
PQExpBuffer query;
|
||||
PGresult *res;
|
||||
@ -18502,6 +18502,11 @@ getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts)
|
||||
return pg_strdup("NONE");
|
||||
}
|
||||
|
||||
/* see if we have the result cached in the type's TypeInfo record */
|
||||
typeInfo = findTypeByOid(oid);
|
||||
if (typeInfo && typeInfo->ftypname)
|
||||
return pg_strdup(typeInfo->ftypname);
|
||||
|
||||
query = createPQExpBuffer();
|
||||
appendPQExpBuffer(query, "SELECT pg_catalog.format_type('%u'::pg_catalog.oid, NULL)",
|
||||
oid);
|
||||
@ -18514,6 +18519,10 @@ getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts)
|
||||
PQclear(res);
|
||||
destroyPQExpBuffer(query);
|
||||
|
||||
/* cache a copy for later requests */
|
||||
if (typeInfo)
|
||||
typeInfo->ftypname = pg_strdup(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -167,9 +167,11 @@ typedef struct _typeInfo
|
||||
DumpableObject dobj;
|
||||
|
||||
/*
|
||||
* Note: dobj.name is the pg_type.typname entry. format_type() might
|
||||
* produce something different than typname
|
||||
* Note: dobj.name is the raw pg_type.typname entry. ftypname is the
|
||||
* result of format_type(), which will be quoted if needed, and might be
|
||||
* schema-qualified too.
|
||||
*/
|
||||
char *ftypname;
|
||||
char *rolname; /* name of owner, or empty string */
|
||||
char *typacl;
|
||||
char *rtypacl;
|
||||
|
Loading…
x
Reference in New Issue
Block a user