Content-Length: 23563 | pFad | https://postgr.es/c/2f1ed9d98

git.postgresql.org Git - postgresql.git/commitdiff
Cache the results of format_type() queries in pg_dump.
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 31 Aug 2021 17:53:33 +0000 (13:53 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 31 Aug 2021 17:53:50 +0000 (13:53 -0400)
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

src/bin/pg_dump/pg_dump.c
src/bin/pg_dump/pg_dump.h

index d181946ad7a7bab60a7d694d6418fb34f8ee6273..9aae8f8f55cf28f0f1a72f24f0dc403c4c15eef6 100644 (file)
@@ -4981,6 +4981,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));
@@ -18611,12 +18612,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;
@@ -18633,6 +18633,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);
@@ -18645,6 +18650,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;
 }
 
index 162a524303dc8677d40a3e37d1ce9d8e06122638..0a29919c13c2f4ed049d65b7a14cf63cfabb1186 100644 (file)
@@ -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;








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: https://postgr.es/c/2f1ed9d98

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy